From d9ae5e50285a902cf5f5a520e64838a9322896e9 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Sun, 9 Nov 2014 18:27:37 +0000 Subject: [PATCH 001/426] Add pncounter & orset --- src/crdt_pncounter.erl | 182 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/crdt_pncounter.erl diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl new file mode 100644 index 000000000..5985e4a8a --- /dev/null +++ b/src/crdt_pncounter.erl @@ -0,0 +1,182 @@ +%% -*- coding: utf-8 -*- +%% ------------------------------------------------------------------- +%% +%% crdt_pncounter: A convergent, replicated, state based PN counter +%% +%% +%% ------------------------------------------------------------------- + +%% @doc +%% A PN-Counter CRDT. A PN-Counter is essentially two G-Counters: one for increments and +%% one for decrements. The value of the counter is the difference between the value of the +%% Positive G-Counter and the value of the Negative G-Counter. +%% +%% +%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of +%% Convergent and Commutative Replicated Data Types. [http://hal.upmc.fr/inria-00555588/] +%% +%% @end + +-module(crdt_pncounter). + +-export([new/0, new/1, value/1, value/2, update/2]). +-export([parent_clock/2, update/3, equal/2]). + +%% EQC API +-ifdef(EQC). +-include_lib("eqc/include/eqc.hrl"). +-export([gen_op/0, update_expected/3, eqc_state_value/1, init_state/0, generate/0]). +-endif. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-export_type([pncounter/0, pncounter_op/0]). + +-opaque pncounter() :: {Inc::non_neg_integer(), Dec::non_neg_integer()}. +-type pncounter_op() :: riak_dt_gcounter:gcounter_op() | decrement_op(). +-type decrement_op() :: decrement | {decrement, pos_integer()}. +-type pncounter_q() :: positive | negative. + +%% @doc Create a new, empty `pncounter()' +-spec new() -> pncounter(). +new() -> + {0,0}. + +%% @doc Create a `pncounter()' with an initial `Value' for `Actor'. +-spec new(integer()) -> pncounter(). +new(Value) when Value > 0 -> + update({increment, Value}, new()); +new(Value) when Value < 0 -> + update({decrement, Value * -1}, new()); +new(_Zero) -> + new(). + +%% @doc no-op +-spec parent_clock(riak_dt_vclock:vclock(), pncounter()) -> + pncounter(). +parent_clock(_Clock, Cntr) -> + Cntr. + +%% @doc The single, total value of a `pncounter()' +-spec value(pncounter()) -> integer(). +value(PNCnt) -> + {Inc, Dec} = PNCnt, + Inc-Dec. + +%% @doc query the parts of a `pncounter()' +%% valid queries are `positive' or `negative'. +-spec value(pncounter_q(), pncounter()) -> integer(). +value(positive, PNCnt) -> + {Inc, _Dec} = PNCnt, + Inc; +value(negative, PNCnt) -> + {_Inc, Dec} = PNCnt, + Dec. + +%% @doc Update a `pncounter()'. The first argument is either the atom +%% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or +%% `{decrement, pos_integer()}'. In the case of the former, the operation's amount +%% is `1'. Otherwise it is the value provided in the tuple's second element. +%% `Actor' is any term, and the 3rd argument is the `pncounter()' to update. +%% +%% returns the updated `pncounter()' +-spec update(pncounter_op(), pncounter()) -> {ok, pncounter()}. +update(increment, PNCnt) -> + update({increment, 1}, PNCnt); +update(decrement, PNCnt) -> + update({decrement, 1}, PNCnt); +update({_IncrDecr, 0}, PNCnt) -> + {ok, PNCnt}; +update({increment, By}, PNCnt) when is_integer(By), By > 0 -> + {ok, increment_by(By, PNCnt)}; +update({increment, By}, PNCnt) when is_integer(By), By < 0 -> + update({decrement, -By}, PNCnt); +update({decrement, By}, PNCnt) when is_integer(By), By > 0 -> + {ok, decrement_by(By, PNCnt)}. + +update(Op, Cntr, _Ctx) -> + update(Op, Cntr). + +-spec equal(pncounter(), pncounter()) -> boolean(). +equal({Inc1, Dec1}, {Inc2, Dec2}) -> + case Inc1 of + Inc2 -> + case Dec1 of + Dec2 -> + true; + _ -> + false + end; + _ -> + false + end. + + +-include("../deps/riak_dt/include/riak_dt_tags.hrl"). +-define(TAG, ?DT_PNCOUNTER_TAG). +-define(V1_VERS, 1). +-define(V2_VERS, 2). + +% Priv +-spec increment_by(pos_integer(), pncounter()) -> pncounter(). +increment_by(Increment, PNCnt) -> + {Inc, Dec} = PNCnt, + {Inc+Increment, Dec}. + +-spec decrement_by(pos_integer(), pncounter()) -> pncounter(). +decrement_by(Decrement, PNCnt) -> + {Inc, Dec} = PNCnt, + {Inc, Dec+Decrement}. + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). + +new_test() -> + ?assertEqual({0,0}, new()). + +value_test() -> + PNCnt1 = {4,0}, + PNCnt2 = {8,4}, + PNCnt3 = {4,4}, + ?assertEqual(4, value(PNCnt1)), + ?assertEqual(4, value(PNCnt2)), + ?assertEqual(0, value(PNCnt3)). + +update_increment_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 1}, PNCnt0), + {ok, PNCnt2} = update({increment, 2}, PNCnt1), + {ok, PNCnt3} = update({increment, 1}, PNCnt2), + ?assertEqual({4,0}, PNCnt3). + +update_increment_by_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 7}, PNCnt0), + ?assertEqual({7,0}, PNCnt1). + +update_decrement_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 1}, PNCnt0), + {ok, PNCnt2} = update({increment, 2}, PNCnt1), + {ok, PNCnt3} = update({increment, 1}, PNCnt2), + {ok, PNCnt4} = update({decrement, 1}, PNCnt3), + ?assertEqual({4,1}, PNCnt4). + +update_decrement_by_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 7}, PNCnt0), + {ok, PNCnt2} = update({decrement, 5}, PNCnt1), + ?assertEqual({7, 5}, PNCnt2). + +equal_test() -> + PNCnt1 = {4,2}, + PNCnt2 = {2,0}, + PNCnt3 = {2,0}, + ?assertNot(equal(PNCnt1, PNCnt2)), + ?assert(equal(PNCnt2, PNCnt3)). + +-endif. From b6ca0aa736dba5b189cf8c6f2ff1890a1b40b704 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Sun, 16 Nov 2014 19:10:56 +0000 Subject: [PATCH 002/426] Adding test --- src/crdt_pncounter.erl | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index 5985e4a8a..c228779c5 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -19,7 +19,7 @@ -module(crdt_pncounter). --export([new/0, new/1, value/1, value/2, update/2]). +-export([new/0, new/1, value/1, value/2, update/2, to_binary/1, from_binary/1]). -export([parent_clock/2, update/3, equal/2]). %% EQC API @@ -32,9 +32,10 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --export_type([pncounter/0, pncounter_op/0]). +-export_type([pncounter/0, pncounter_op/0, binary_pncounter/0]). -opaque pncounter() :: {Inc::non_neg_integer(), Dec::non_neg_integer()}. +-type binary_pncounter() :: binary(). -type pncounter_op() :: riak_dt_gcounter:gcounter_op() | decrement_op(). -type decrement_op() :: decrement | {decrement, pos_integer()}. -type pncounter_q() :: positive | negative. @@ -113,12 +114,20 @@ equal({Inc1, Dec1}, {Inc2, Dec2}) -> false end. - -include("../deps/riak_dt/include/riak_dt_tags.hrl"). -define(TAG, ?DT_PNCOUNTER_TAG). -define(V1_VERS, 1). -define(V2_VERS, 2). +-spec to_binary(pncounter()) -> binary_pncounter(). +to_binary(PNCounter) -> + %% @TODO something smarter + <>. + +from_binary(<>) -> + %% @TODO something smarter + binary_to_term(Bin). + % Priv -spec increment_by(pos_integer(), pncounter()) -> pncounter(). increment_by(Increment, PNCnt) -> @@ -179,4 +188,10 @@ equal_test() -> ?assertNot(equal(PNCnt1, PNCnt2)), ?assert(equal(PNCnt2, PNCnt3)). +binary_test() -> + PNCnt1 = {4,2}, + BinaryPNCnt1 = to_binary(PNCnt1), + PNCnt2 = from_binary(BinaryPNCnt1), + ?assert(equal(PNCnt1, PNCnt2)). + -endif. From d9e75dcb11d84c515d19041beb3e9ba831a92c0f Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 18 Nov 2014 17:27:27 +0000 Subject: [PATCH 003/426] Implement op-based counter, set & Change downstream generator --- src/crdt_pncounter.erl | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index c228779c5..3d67a74ce 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -19,8 +19,8 @@ -module(crdt_pncounter). --export([new/0, new/1, value/1, value/2, update/2, to_binary/1, from_binary/1]). --export([parent_clock/2, update/3, equal/2]). +-export([new/0, new/1, value/1, value/2, update/2, generate_downstream/3, to_binary/1, from_binary/1]). +-export([equal/2]). %% EQC API -ifdef(EQC). @@ -54,11 +54,6 @@ new(Value) when Value < 0 -> new(_Zero) -> new(). -%% @doc no-op --spec parent_clock(riak_dt_vclock:vclock(), pncounter()) -> - pncounter(). -parent_clock(_Clock, Cntr) -> - Cntr. %% @doc The single, total value of a `pncounter()' -spec value(pncounter()) -> integer(). @@ -76,6 +71,17 @@ value(negative, PNCnt) -> {_Inc, Dec} = PNCnt, Dec. +-spec generate_downstream(pncounter_op(), riak_dt:actor(), pncounter()) -> {ok, pncounter_op()}. +generate_downstream(increment, _Actor, _PNCnt) -> + {ok, {increment, 1}}; +generate_downstream(decrement, _Actor, _PNCnt) -> + {ok, {decrement, 1}}; +generate_downstream({increment, By}, _Actor, _PNCnt) -> + {ok, {increment, By}}; +generate_downstream({decrement, By}, _Actor, _PNCnt) -> + {ok, {decrement, By}}. + + %% @doc Update a `pncounter()'. The first argument is either the atom %% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or %% `{decrement, pos_integer()}'. In the case of the former, the operation's amount @@ -97,8 +103,6 @@ update({increment, By}, PNCnt) when is_integer(By), By < 0 -> update({decrement, By}, PNCnt) when is_integer(By), By > 0 -> {ok, decrement_by(By, PNCnt)}. -update(Op, Cntr, _Ctx) -> - update(Op, Cntr). -spec equal(pncounter(), pncounter()) -> boolean(). equal({Inc1, Dec1}, {Inc2, Dec2}) -> From e5c495f9cdce1f0312510006d942e28d794cbf10 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 24 Nov 2014 17:18:40 +0000 Subject: [PATCH 004/426] Adding orset test --- src/crdt_pncounter.erl | 58 ++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index 3d67a74ce..567e632bc 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -36,8 +36,8 @@ -opaque pncounter() :: {Inc::non_neg_integer(), Dec::non_neg_integer()}. -type binary_pncounter() :: binary(). --type pncounter_op() :: riak_dt_gcounter:gcounter_op() | decrement_op(). --type decrement_op() :: decrement | {decrement, pos_integer()}. +-type pncounter_op() :: {riak_dt_gcounter:gcounter_op(), binary()} | decrement_op(). +-type decrement_op() :: decrement | {decrement, pos_integer(), binary()}. -type pncounter_q() :: positive | negative. %% @doc Create a new, empty `pncounter()' @@ -48,9 +48,9 @@ new() -> %% @doc Create a `pncounter()' with an initial `Value' for `Actor'. -spec new(integer()) -> pncounter(). new(Value) when Value > 0 -> - update({increment, Value}, new()); + update({{increment, Value}, unique(1)}, new()); new(Value) when Value < 0 -> - update({decrement, Value * -1}, new()); + update({decrement, Value * -1, unique(1)}, new()); new(_Zero) -> new(). @@ -72,14 +72,14 @@ value(negative, PNCnt) -> Dec. -spec generate_downstream(pncounter_op(), riak_dt:actor(), pncounter()) -> {ok, pncounter_op()}. -generate_downstream(increment, _Actor, _PNCnt) -> - {ok, {increment, 1}}; -generate_downstream(decrement, _Actor, _PNCnt) -> - {ok, {decrement, 1}}; -generate_downstream({increment, By}, _Actor, _PNCnt) -> - {ok, {increment, By}}; -generate_downstream({decrement, By}, _Actor, _PNCnt) -> - {ok, {decrement, By}}. +generate_downstream(increment, Actor, _PNCnt) -> + {ok, {{increment, 1}, unique(Actor)}}; +generate_downstream(decrement, Actor, _PNCnt) -> + {ok, {{decrement, 1}, unique(Actor)}}; +generate_downstream({increment, By}, Actor, _PNCnt) -> + {ok, {{increment, By}, unique(Actor)}}; +generate_downstream({decrement, By}, Actor, _PNCnt) -> + {ok, {{decrement, By}, unique(Actor)}}. %% @doc Update a `pncounter()'. The first argument is either the atom @@ -90,17 +90,13 @@ generate_downstream({decrement, By}, _Actor, _PNCnt) -> %% %% returns the updated `pncounter()' -spec update(pncounter_op(), pncounter()) -> {ok, pncounter()}. -update(increment, PNCnt) -> - update({increment, 1}, PNCnt); -update(decrement, PNCnt) -> - update({decrement, 1}, PNCnt); -update({_IncrDecr, 0}, PNCnt) -> +update({{_IncrDecr, 0}, _Token}, PNCnt) -> {ok, PNCnt}; -update({increment, By}, PNCnt) when is_integer(By), By > 0 -> +update({{increment, By}, _Token}, PNCnt) when is_integer(By), By > 0 -> {ok, increment_by(By, PNCnt)}; -update({increment, By}, PNCnt) when is_integer(By), By < 0 -> +update({{increment, By}, _Token}, PNCnt) when is_integer(By), By < 0 -> update({decrement, -By}, PNCnt); -update({decrement, By}, PNCnt) when is_integer(By), By > 0 -> +update({{decrement, By}, _Token}, PNCnt) when is_integer(By), By > 0 -> {ok, decrement_by(By, PNCnt)}. @@ -143,6 +139,8 @@ decrement_by(Decrement, PNCnt) -> {Inc, Dec} = PNCnt, {Inc, Dec+Decrement}. +unique(_Actor) -> + crypto:strong_rand_bytes(20). %% =================================================================== %% EUnit tests %% =================================================================== @@ -161,28 +159,28 @@ value_test() -> update_increment_test() -> PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 1}, PNCnt0), - {ok, PNCnt2} = update({increment, 2}, PNCnt1), - {ok, PNCnt3} = update({increment, 1}, PNCnt2), + {ok, PNCnt1} = update({{increment, 1}, 1}, PNCnt0), + {ok, PNCnt2} = update({{increment, 2}, 1}, PNCnt1), + {ok, PNCnt3} = update({{increment, 1}, 1}, PNCnt2), ?assertEqual({4,0}, PNCnt3). update_increment_by_test() -> PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 7}, PNCnt0), + {ok, PNCnt1} = update({{increment, 7}, 1}, PNCnt0), ?assertEqual({7,0}, PNCnt1). update_decrement_test() -> PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 1}, PNCnt0), - {ok, PNCnt2} = update({increment, 2}, PNCnt1), - {ok, PNCnt3} = update({increment, 1}, PNCnt2), - {ok, PNCnt4} = update({decrement, 1}, PNCnt3), + {ok, PNCnt1} = update({{increment, 1}, 1}, PNCnt0), + {ok, PNCnt2} = update({{increment, 2}, 1}, PNCnt1), + {ok, PNCnt3} = update({{increment, 1}, 1}, PNCnt2), + {ok, PNCnt4} = update({{decrement, 1}, 1}, PNCnt3), ?assertEqual({4,1}, PNCnt4). update_decrement_by_test() -> PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 7}, PNCnt0), - {ok, PNCnt2} = update({decrement, 5}, PNCnt1), + {ok, PNCnt1} = update({{increment, 7}, 1}, PNCnt0), + {ok, PNCnt2} = update({{decrement, 5}, 1}, PNCnt1), ?assertEqual({7, 5}, PNCnt2). equal_test() -> From 634f88be894b2829b82ecfed6fbfe2926715846b Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 24 Nov 2014 18:51:04 +0000 Subject: [PATCH 005/426] Add comments --- src/crdt_pncounter.erl | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index 567e632bc..050d7e6fd 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -7,9 +7,9 @@ %% ------------------------------------------------------------------- %% @doc -%% A PN-Counter CRDT. A PN-Counter is essentially two G-Counters: one for increments and +%% A PN-Counter CRDT. A PN-Counter is represented as two non-negative integers: one for increments and %% one for decrements. The value of the counter is the difference between the value of the -%% Positive G-Counter and the value of the Negative G-Counter. +%% positive counter and the value of the negative counter. %% %% %% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of @@ -54,7 +54,6 @@ new(Value) when Value < 0 -> new(_Zero) -> new(). - %% @doc The single, total value of a `pncounter()' -spec value(pncounter()) -> integer(). value(PNCnt) -> @@ -71,6 +70,14 @@ value(negative, PNCnt) -> {_Inc, Dec} = PNCnt, Dec. +%% @doc Generate a downstream operation. +%% The first parameter is either `increment' or `decrement' or the two tuples +%% `{increment, pos_integer()}' or `{decrement, pos_integer()}'. The second parameter +%% is the actor and the third parameter is the pncounter (both parameters are not actually used). +%% +%% Returns a tuple representing the downstream operation and a unique identifier. The unique +%% identifier is to ensure that the two same operations (e.g. two {increment, 1}) in a single +%% transaction will not be ingored, which is caused by our implementation. -spec generate_downstream(pncounter_op(), riak_dt:actor(), pncounter()) -> {ok, pncounter_op()}. generate_downstream(increment, Actor, _PNCnt) -> {ok, {{increment, 1}, unique(Actor)}}; @@ -84,9 +91,10 @@ generate_downstream({decrement, By}, Actor, _PNCnt) -> %% @doc Update a `pncounter()'. The first argument is either the atom %% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or -%% `{decrement, pos_integer()}'. In the case of the former, the operation's amount +%% `{decrement, pos_integer()}', followed by a unique token, which is not used here. +%% In the case of the former, the operation's amount %% is `1'. Otherwise it is the value provided in the tuple's second element. -%% `Actor' is any term, and the 3rd argument is the `pncounter()' to update. +%% The 2nd argument is the `pncounter()' to update. %% %% returns the updated `pncounter()' -spec update(pncounter_op(), pncounter()) -> {ok, pncounter()}. @@ -95,11 +103,15 @@ update({{_IncrDecr, 0}, _Token}, PNCnt) -> update({{increment, By}, _Token}, PNCnt) when is_integer(By), By > 0 -> {ok, increment_by(By, PNCnt)}; update({{increment, By}, _Token}, PNCnt) when is_integer(By), By < 0 -> - update({decrement, -By}, PNCnt); + {ok, decrement_by(-By, PNCnt)}; update({{decrement, By}, _Token}, PNCnt) when is_integer(By), By > 0 -> - {ok, decrement_by(By, PNCnt)}. + {ok, decrement_by(By, PNCnt)}; +update({{decrement, By}, _Token}, PNCnt) when is_integer(By), By < 0 -> + {ok, increment_by(-By, PNCnt)}. +%% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both +%% of their positive and negative entries are equal. -spec equal(pncounter(), pncounter()) -> boolean(). equal({Inc1, Dec1}, {Inc2, Dec2}) -> case Inc1 of @@ -149,6 +161,7 @@ unique(_Actor) -> new_test() -> ?assertEqual({0,0}, new()). +%% @doc test the correctness of `value()' function value_test() -> PNCnt1 = {4,0}, PNCnt2 = {8,4}, @@ -157,6 +170,7 @@ value_test() -> ?assertEqual(4, value(PNCnt2)), ?assertEqual(0, value(PNCnt3)). +%% @doc test the correctness of increment without parameter. update_increment_test() -> PNCnt0 = new(), {ok, PNCnt1} = update({{increment, 1}, 1}, PNCnt0), @@ -164,11 +178,13 @@ update_increment_test() -> {ok, PNCnt3} = update({{increment, 1}, 1}, PNCnt2), ?assertEqual({4,0}, PNCnt3). +%% @doc test the correctness of increment by some numbers. update_increment_by_test() -> PNCnt0 = new(), {ok, PNCnt1} = update({{increment, 7}, 1}, PNCnt0), ?assertEqual({7,0}, PNCnt1). +%% @doc test the correctness of decrement. update_decrement_test() -> PNCnt0 = new(), {ok, PNCnt1} = update({{increment, 1}, 1}, PNCnt0), From 4a7de053a85fffef6403e946d74e72814e1834f6 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 12 Jan 2015 18:58:51 +0000 Subject: [PATCH 006/426] Add info and change to new CRDTs --- src/crdt_pncounter.erl | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index 050d7e6fd..1a7e9043e 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -1,16 +1,42 @@ -%% -*- coding: utf-8 -*- %% ------------------------------------------------------------------- %% -%% crdt_pncounter: A convergent, replicated, state based PN counter +%% crdt_pncounter: A convergent, replicated, operation based PN-Counter. %% +%% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. %% %% ------------------------------------------------------------------- + %% @doc -%% A PN-Counter CRDT. A PN-Counter is represented as two non-negative integers: one for increments and -%% one for decrements. The value of the counter is the difference between the value of the -%% positive counter and the value of the negative counter. +%% An operation-based PN-Counter CRDT. +%% A PN-Counter is represented as two non-negative integers: one for increments and one for decrements. +%% The value of the counter is the difference between the value of the positive counter and the value +%% of the negative counter. +%% +%% As the data structure is operation-based, to issue an operation, one should firstly call +%% `generate_downstream/3' to get the downstream version of the operation and then call `update/2'. %% +%% This file is adapted from riak_dt_pncounter, a state-based implementation of PN-Counter. +%% The changes are as follows: +%% 1. `generate_downstream/3' is added, as this is a requirement for op-based CRDTs. +%% For PN-Counter, there is actually little difference between their op-based and state-based +%% implementation. Having `generate_downstream/3' is merely to keep the interface of op-based +%% CRDTs compatible with each other. +%% 2. `merge/2' is removed. %% %% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of %% Convergent and Commutative Replicated Data Types. [http://hal.upmc.fr/inria-00555588/] From a743c809538f636f516040ede72b074987992433 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 13 Jan 2015 10:49:05 +0000 Subject: [PATCH 007/426] Adjust line length --- src/crdt_pncounter.erl | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index 1a7e9043e..b9602b851 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -23,19 +23,21 @@ %% @doc %% An operation-based PN-Counter CRDT. -%% A PN-Counter is represented as two non-negative integers: one for increments and one for decrements. -%% The value of the counter is the difference between the value of the positive counter and the value -%% of the negative counter. +%% A PN-Counter is represented as two non-negative integers: one for increments +%% and one for decrements. The value of the counter is the difference between the +%% value of the positive counter and the value of the negative counter. %% -%% As the data structure is operation-based, to issue an operation, one should firstly call -%% `generate_downstream/3' to get the downstream version of the operation and then call `update/2'. +%% As the data structure is operation-based, to issue an operation, one should +%% firstly call `generate_downstream/3' to get the downstream version of the +%% operation and then call `update/2'. %% -%% This file is adapted from riak_dt_pncounter, a state-based implementation of PN-Counter. +%% This file is adapted from riak_dt_pncounter, a state-based implementation of +%% PN-Counter. %% The changes are as follows: %% 1. `generate_downstream/3' is added, as this is a requirement for op-based CRDTs. -%% For PN-Counter, there is actually little difference between their op-based and state-based -%% implementation. Having `generate_downstream/3' is merely to keep the interface of op-based -%% CRDTs compatible with each other. +%% For PN-Counter, there is actually little difference between their op-based and +%% state-based implementation. Having `generate_downstream/3' is merely to keep +%% the interface of op-based CRDTs compatible with each other. %% 2. `merge/2' is removed. %% %% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of From b200db0760f38b70b42738430d77579b9329152a Mon Sep 17 00:00:00 2001 From: Christopher Meiklejohn Date: Mon, 12 Jan 2015 11:55:50 -0500 Subject: [PATCH 008/426] Fix build. Resolve problems in the build where under a defined EQC compile, it would attempt to export functions which were removed from the module. --- src/crdt_pncounter.erl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index b9602b851..bbaadd85a 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -50,12 +50,6 @@ -export([new/0, new/1, value/1, value/2, update/2, generate_downstream/3, to_binary/1, from_binary/1]). -export([equal/2]). -%% EQC API --ifdef(EQC). --include_lib("eqc/include/eqc.hrl"). --export([gen_op/0, update_expected/3, eqc_state_value/1, init_state/0, generate/0]). --endif. - -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. From 25bba182dffcb19c326f663e6e4f3c97e39ccad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sat, 6 Jun 2015 21:50:06 +0300 Subject: [PATCH 009/426] Use "include_lib" instead of "include ../deps/" --- src/crdt_pncounter.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index bbaadd85a..612e411f2 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -148,7 +148,7 @@ equal({Inc1, Dec1}, {Inc2, Dec2}) -> false end. --include("../deps/riak_dt/include/riak_dt_tags.hrl"). +-include_lib("riak_dt/include/riak_dt_tags.hrl"). -define(TAG, ?DT_PNCOUNTER_TAG). -define(V1_VERS, 1). -define(V2_VERS, 2). From dbc95ca1220af86b3de677a356cbee2749a499ab Mon Sep 17 00:00:00 2001 From: "Alejandro Z. Tomsic" Date: Thu, 17 Sep 2015 18:25:16 +0200 Subject: [PATCH 010/426] changed certification --- src/crdt_pncounter.erl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl index 612e411f2..9dc72b5c9 100644 --- a/src/crdt_pncounter.erl +++ b/src/crdt_pncounter.erl @@ -48,7 +48,7 @@ -module(crdt_pncounter). -export([new/0, new/1, value/1, value/2, update/2, generate_downstream/3, to_binary/1, from_binary/1]). --export([equal/2]). +-export([equal/2, is_operation/1]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -175,6 +175,13 @@ decrement_by(Decrement, PNCnt) -> unique(_Actor) -> crypto:strong_rand_bytes(20). + +%% @doc The following operation verifies +%% that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(Operation) -> + riak_dt_pncounter:is_operation(Operation). + %% =================================================================== %% EUnit tests %% =================================================================== From 4bc5320f02448e2c35d0b666388285f5deaaf671 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Sun, 9 Nov 2014 18:27:37 +0000 Subject: [PATCH 011/426] Add pncounter & orset --- src/crdt_orset.erl | 298 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 src/crdt_orset.erl diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl new file mode 100644 index 000000000..5600e56ba --- /dev/null +++ b/src/crdt_orset.erl @@ -0,0 +1,298 @@ +%% ------------------------------------------------------------------- +%% +%% crdt_orset: A convergent, replicated, state based observe remove set +%% +%% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(crdt_orset). + + +%% API +-export([new/0, value/1, update/3, equal/2, + to_binary/1, from_binary/1, value/2, precondition_context/1, stats/1, stat/2]). +-export([update/4, parent_clock/2]). + +-ifdef(EQC). +-include_lib("eqc/include/eqc.hrl"). +-endif. + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +%% EQC API +-ifdef(EQC). +-export([init_state/0, gen_op/0, update_expected/3, eqc_state_value/1]). +-endif. + +-export_type([orset/0, binary_orset/0, orset_op/0]). +-opaque orset() :: orddict:orddict(). + +-type binary_orset() :: binary(). %% A binary that from_binary/1 will operate on. + +-type orset_op() :: {add, member()} | {remove, member()} | + {get_downstream, member()}| + {add_all, [member()]} | {remove_all, [member()]} | + {update, [orset_op()]}. + +-type actor() :: riak_dt:actor(). +-type member() :: term(). + +-spec new() -> orset(). +new() -> + orddict:new(). + +-spec value(orset()) -> [member()]. +value(ORDict) -> + orddict:fetch_keys(ORDict). + +-spec value(any(), orset()) -> [member()] | orddict:orddict(). +value({fragment, Elem}, ORSet) -> + case value({tokens, Elem}, ORSet) of + [] -> + orddict:new(); + Tokens -> + orddict:store(Elem, Tokens, orddict:new()) + end; +value({tokens, Elem}, ORSet) -> + case orddict:find(Elem, ORSet) of + error -> + orddict:new(); + {ok, Tokens} -> + Tokens + end; +value(_,ORSet) -> + value(ORSet). + +-spec update(orset_op(), actor(), orset()) -> {ok, orset()} | + {error, {precondition ,{not_present, member()}}}. +update({add,Elem}, Actor, _ORDict) -> + Token = unique(Actor), + {ok, {downstream_add, {Elem,[Token]}}}; +update({downstream_add, {Elem, [Token|_]}}, _Actor, ORDict) -> + add_elem(Elem,Token,ORDict); +update({add_all,Elems}, Actor, _ORDict0) -> + DownstreamOp = lists:foldl(fun(Elem, Sum) -> + Token = unique(Actor), + Sum++[{Elem, [Token]}] + end, [], Elems), + {ok, {downstream_add_all, DownstreamOp}}; +update({downstream_add_all,Elems}, Actor, ORDict0) -> + OD = lists:foldl(fun(Elem,ORDict) -> + {ok, ORDict1} = update({downstream_add,Elem},Actor,ORDict), + ORDict1 + end, ORDict0, Elems), + {ok, OD}; +update({remove, Elem}, _Actor, ORDict) -> + ToRemove = value({tokens, Elem}, ORDict), + {ok, {downstream_remove, {Elem, ToRemove}}}; +update({downstream_remove, Elem}, _Actor, ORDict) -> + remove_elem(Elem, ORDict); +update({remove_all,Elems}, _Actor, ORDict) -> + ToRemove = lists:foldl(fun(Elem, Sum) -> Sum++[{Elem, value({tokens, Elem}, ORDict)}] end, [], Elems), + {ok, {downstream_remove_all, ToRemove}}; +update({downstream_remove_all,Elems}, _Actor, ORDict0) -> + remove_elems(Elems, ORDict0); +update({update, Ops}, Actor, ORDict) -> + apply_ops(Ops, Actor, ORDict). + +-spec update(orset_op(), actor(), orset(), riak_dt:context()) -> + {ok, orset()} | {error, {precondition ,{not_present, member()}}}. +update(Op, Actor, ORDict, _Ctx) -> + update(Op, Actor, ORDict). + +-spec parent_clock(riak_dt_vclock:vclock(), orset()) -> orset(). +parent_clock(_Clock, ORSet) -> + ORSet. + +-spec equal(orset(), orset()) -> boolean(). +equal(ORDictA, ORDictB) -> + ORDictA == ORDictB. % Everything inside is ordered, so this should work + +%% @doc the precondition context is a fragment of the CRDT that +%% operations with pre-conditions can be applied too. In the case of +%% OR-Sets this is the set of adds observed. The system can then +%% apply a remove to this context and merge it with a replica. +%% Especially useful for hybrid op/state systems where the context of +%% an operation is needed at a replica without sending the entire +%% state to the client. +-spec precondition_context(orset()) -> orset(). +precondition_context(ORDict) -> + orddict:fold(fun(Elem, Tokens, ORDict1) -> + case minimum_tokens(Tokens) of + [] -> ORDict1; + Tokens1 -> orddict:store(Elem, Tokens1, ORDict1) + end + end, orddict:new(), ORDict). + +-spec stats(orset()) -> [{atom(), number()}]. +stats(ORSet) -> + [ {S, stat(S, ORSet)} || S <- [element_count] ]. + +-spec stat(atom(), orset()) -> number() | undefined. +stat(element_count, ORSet) -> + orddict:size(ORSet); +stat(_, _) -> undefined. + +-include("../deps/riak_dt/include/riak_dt_tags.hrl"). +-define(TAG, ?DT_ORSET_TAG). +-define(V1_VERS, 1). + +-spec to_binary(orset()) -> binary_orset(). +to_binary(ORSet) -> + %% @TODO something smarter + <>. + +from_binary(<>) -> + %% @TODO something smarter + binary_to_term(Bin). + +%% Private +add_elem(Elem,Token,ORDict) -> + case orddict:find(Elem,ORDict) of + {ok, Tokens} -> + {ok, orddict:store(Elem, Tokens++[Token], ORDict)}; + error -> + {ok, orddict:store(Elem, [Token], ORDict)} + end. + +remove_elem({Elem,RemoveTokens},ORDict) -> + case orddict:find(Elem,ORDict) of + {ok, Tokens} -> + RestTokens = Tokens--RemoveTokens, + case RestTokens of + [] -> + {ok, orddict:erase(Elem, ORDict)}; + _ -> + {ok, orddict:store(Elem, Tokens--RemoveTokens, ORDict)} + end; + error -> + {error, {precondition, {not_present, Elem}}} + end. + +remove_elems([], ORDict) -> + {ok, ORDict}; +remove_elems([Elem|Rest], ORDict) -> + case remove_elem(Elem,ORDict) of + {ok, ORDict1} -> remove_elems(Rest, ORDict1); + Error -> Error + end. + +apply_ops([], _Actor, ORDict) -> + {ok, ORDict}; +apply_ops([Op | Rest], Actor, ORDict) -> + case update(Op, Actor, ORDict) of + {ok, ORDict1} -> apply_ops(Rest, Actor, ORDict1); + Error -> Error + end. + +unique(_Actor) -> + crypto:strong_rand_bytes(20). + +minimum_tokens(Tokens) -> + orddict:filter(fun(_Token, Removed) -> + not Removed + end, Tokens). + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). +new_test() -> + ?assertEqual(orddict:new(), new()). + +add_test() -> + Set1 = new(), + {ok, DownstreamOp1} = update({add, <<"foo">>}, 1, Set1), + ?assertMatch({downstream_add, {<<"foo">>, _}}, DownstreamOp1), + {ok, DownstreamOp2} = update({add_all, [<<"li">>,<<"manu">>]}, 1, Set1), + ?assertMatch({downstream_add_all, [{<<"li">>, _}, {<<"manu">>, _}]}, DownstreamOp2), + {ok, Set2} = update(DownstreamOp1, 1, Set1), + {_, Elem1} = DownstreamOp1, + ?assertEqual([Elem1], orddict:to_list(Set2)), + {ok, Set3} = update(DownstreamOp2, 1, Set1), + {_, Elems2} = DownstreamOp2, + ?assertEqual(Elems2, orddict:to_list(Set3)). + +value_test() -> + Set1 = new(), + {ok, DownstreamOp1} = update({add, <<"foo">>}, 1, Set1), + ?assertEqual([], value(Set1)), + {ok, Set2} = update(DownstreamOp1, 1, Set1), + ?assertEqual([<<"foo">>], value(Set2)), + {ok, DownstreamOp2} = update({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set2), + {ok, Set3} = update(DownstreamOp2, 1, Set2), + ?assertEqual([<<"foo">>, <<"li">>, <<"manu">>], value(Set3)), + + {_, {_, Token1}}=DownstreamOp1, + {_, [{_, Token2}|_]}=DownstreamOp2, + ?assertEqual(Token1, value({tokens, <<"foo">>}, Set2)), + ?assertEqual(Token1++Token2, value({tokens, <<"foo">>}, Set3)), + + ?assertEqual(orddict:store(<<"foo">>, Token1++Token2, orddict:new()), value({fragment, <<"foo">>}, Set3)). + +remove_test() -> + Set1 = new(), + %% Add an element then remove it + {ok, Op1} = update({add, <<"foo">>}, 1, Set1), + {ok, Set2} = update(Op1, 1, Set1), + ?assertEqual([<<"foo">>], value(Set2)), + {ok, Op2} = update({remove, <<"foo">>}, 1, Set2), + {ok, Set3} = update(Op2, 1, Set2), + ?assertEqual([], value(Set3)), + + %% Add many elements then remove part + {ok, Op3} = update({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), + {ok, Set4} = update(Op3, 1, Set1), + ?assertEqual([<<"foo">>, <<"li">>, <<"manu">>], value(Set4)), + + {ok, Op5} = update({remove_all, [<<"foo">>, <<"li">>]},1 , Set4), + {ok, Set5} = update(Op5, 1, Set4), + ?assertEqual([<<"manu">>], value(Set5)), + + %% Remove more than current have + {ok, Op6} = update({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), + {ok, Set6} = update(Op6, 1, Set1), + {ok, Op7} = update({remove_all, [<<"manu">>, <<"test">>]}, 1, Set6), + Result = update(Op7, 1, Set6), + ?assertEqual({error,{precondition,{not_present,<<"test">>}}}, Result). + + +concurrent_add_test() -> + Set1 = new(), + %% Add an element then remove it + {ok, Op1} = update({add, <<"foo">>}, 1, Set1), + {ok, Set2} = update(Op1, 1, Set1), + ?assertEqual([<<"foo">>], value(Set2)), + + %% If remove is concurrent with the second add, will not remove the second added + {ok, Op2} = update({remove, <<"foo">>}, 1, Set2), + + {ok, Op3} = update({add, <<"foo">>}, 1, Set1), + {ok, Set3} = update(Op3, 1, Set2), + ?assertEqual([<<"foo">>], value(Set3)), + + {ok, Set4} = update(Op2, 1, Set3), + ?assertEqual([<<"foo">>], value(Set4)), + + %% If remove follows two adds, remove will remove all + {ok, Op4} = update({remove, <<"foo">>}, 1, Set3), + {ok, Set5} = update(Op4, 1, Set3), + ?assertEqual([], value(Set5)). + From b4b780a6ccb05819d0831e1a5d643b094cb59b72 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Sun, 16 Nov 2014 19:10:56 +0000 Subject: [PATCH 012/426] Adding test --- src/crdt_orset.erl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 5600e56ba..fc98169ed 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -296,3 +296,16 @@ concurrent_add_test() -> {ok, Set5} = update(Op4, 1, Set3), ?assertEqual([], value(Set5)). +binary_test() -> + ORSet1 = new(), + BinaryORSet1 = to_binary(ORSet1), + ORSet2 = from_binary(BinaryORSet1), + ?assert(equal(ORSet1, ORSet2)), + + {ok, Op1} = update({add, <<"foo">>}, 1, ORSet1), + {ok, ORSet3} = update(Op1, 1, ORSet1), + BinaryORSet3 = to_binary(ORSet3), + ORSet4 = from_binary(BinaryORSet3), + ?assert(equal(ORSet3, ORSet4)). + +-endif. From b8da574f4ce6869e9f9859835393aad20ce44b62 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 18 Nov 2014 17:27:27 +0000 Subject: [PATCH 013/426] Implement op-based counter, set & Change downstream generator --- src/crdt_orset.erl | 126 +++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index fc98169ed..53751767f 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -24,9 +24,8 @@ %% API --export([new/0, value/1, update/3, equal/2, +-export([new/0, value/1, generate_downstream/3, update/2, equal/2, to_binary/1, from_binary/1, value/2, precondition_context/1, stats/1, stat/2]). --export([update/4, parent_clock/2]). -ifdef(EQC). -include_lib("eqc/include/eqc.hrl"). @@ -80,46 +79,41 @@ value({tokens, Elem}, ORSet) -> value(_,ORSet) -> value(ORSet). --spec update(orset_op(), actor(), orset()) -> {ok, orset()} | - {error, {precondition ,{not_present, member()}}}. -update({add,Elem}, Actor, _ORDict) -> +-spec generate_downstream(orset_op(), actor(), orset()) -> {ok, orset_op()}. +generate_downstream({add,Elem}, Actor, _ORDict) -> Token = unique(Actor), - {ok, {downstream_add, {Elem,[Token]}}}; -update({downstream_add, {Elem, [Token|_]}}, _Actor, ORDict) -> - add_elem(Elem,Token,ORDict); -update({add_all,Elems}, Actor, _ORDict0) -> + {ok, {add, {Elem,[Token]}}}; +generate_downstream({add_all,Elems}, Actor, _ORDict0) -> DownstreamOp = lists:foldl(fun(Elem, Sum) -> Token = unique(Actor), Sum++[{Elem, [Token]}] end, [], Elems), - {ok, {downstream_add_all, DownstreamOp}}; -update({downstream_add_all,Elems}, Actor, ORDict0) -> + {ok, {add_all, DownstreamOp}}; +generate_downstream({remove, Elem}, _Actor, ORDict) -> + ToRemove = value({tokens, Elem}, ORDict), + {ok, {remove, {Elem, ToRemove}}}; +generate_downstream({remove_all,Elems}, _Actor, ORDict) -> + ToRemove = lists:foldl(fun(Elem, Sum) -> Sum++[{Elem, value({tokens, Elem}, ORDict)}] end, [], Elems), + {ok, {remove_all, ToRemove}}. + + +-spec update(orset_op(), orset()) -> {ok, orset()} | + {error, {precondition ,{not_present, member()}}}. +update({add, {Elem, [Token|_]}}, ORDict) -> + add_elem(Elem,Token,ORDict); +update({add_all,Elems}, ORDict0) -> OD = lists:foldl(fun(Elem,ORDict) -> - {ok, ORDict1} = update({downstream_add,Elem},Actor,ORDict), + {ok, ORDict1} = update({add,Elem},ORDict), ORDict1 end, ORDict0, Elems), {ok, OD}; -update({remove, Elem}, _Actor, ORDict) -> - ToRemove = value({tokens, Elem}, ORDict), - {ok, {downstream_remove, {Elem, ToRemove}}}; -update({downstream_remove, Elem}, _Actor, ORDict) -> +update({remove, Elem}, ORDict) -> remove_elem(Elem, ORDict); -update({remove_all,Elems}, _Actor, ORDict) -> - ToRemove = lists:foldl(fun(Elem, Sum) -> Sum++[{Elem, value({tokens, Elem}, ORDict)}] end, [], Elems), - {ok, {downstream_remove_all, ToRemove}}; -update({downstream_remove_all,Elems}, _Actor, ORDict0) -> +update({remove_all,Elems}, ORDict0) -> remove_elems(Elems, ORDict0); -update({update, Ops}, Actor, ORDict) -> - apply_ops(Ops, Actor, ORDict). - --spec update(orset_op(), actor(), orset(), riak_dt:context()) -> - {ok, orset()} | {error, {precondition ,{not_present, member()}}}. -update(Op, Actor, ORDict, _Ctx) -> - update(Op, Actor, ORDict). +update({update, Ops}, ORDict) -> + apply_ops(Ops, ORDict). --spec parent_clock(riak_dt_vclock:vclock(), orset()) -> orset(). -parent_clock(_Clock, ORSet) -> - ORSet. -spec equal(orset(), orset()) -> boolean(). equal(ORDictA, ORDictB) -> @@ -194,11 +188,11 @@ remove_elems([Elem|Rest], ORDict) -> Error -> Error end. -apply_ops([], _Actor, ORDict) -> +apply_ops([], ORDict) -> {ok, ORDict}; -apply_ops([Op | Rest], Actor, ORDict) -> - case update(Op, Actor, ORDict) of - {ok, ORDict1} -> apply_ops(Rest, Actor, ORDict1); +apply_ops([Op | Rest], ORDict) -> + case update(Op, ORDict) of + {ok, ORDict1} -> apply_ops(Rest, ORDict1); Error -> Error end. @@ -219,25 +213,25 @@ new_test() -> add_test() -> Set1 = new(), - {ok, DownstreamOp1} = update({add, <<"foo">>}, 1, Set1), - ?assertMatch({downstream_add, {<<"foo">>, _}}, DownstreamOp1), - {ok, DownstreamOp2} = update({add_all, [<<"li">>,<<"manu">>]}, 1, Set1), - ?assertMatch({downstream_add_all, [{<<"li">>, _}, {<<"manu">>, _}]}, DownstreamOp2), - {ok, Set2} = update(DownstreamOp1, 1, Set1), + {ok, DownstreamOp1} = generate_downstream({add, <<"foo">>}, 1, Set1), + ?assertMatch({add, {<<"foo">>, _}}, DownstreamOp1), + {ok, DownstreamOp2} = generate_downstream({add_all, [<<"li">>,<<"manu">>]}, 1, Set1), + ?assertMatch({add_all, [{<<"li">>, _}, {<<"manu">>, _}]}, DownstreamOp2), + {ok, Set2} = update(DownstreamOp1, Set1), {_, Elem1} = DownstreamOp1, ?assertEqual([Elem1], orddict:to_list(Set2)), - {ok, Set3} = update(DownstreamOp2, 1, Set1), + {ok, Set3} = update(DownstreamOp2, Set1), {_, Elems2} = DownstreamOp2, ?assertEqual(Elems2, orddict:to_list(Set3)). value_test() -> Set1 = new(), - {ok, DownstreamOp1} = update({add, <<"foo">>}, 1, Set1), + {ok, DownstreamOp1} = generate_downstream({add, <<"foo">>}, 1, Set1), ?assertEqual([], value(Set1)), - {ok, Set2} = update(DownstreamOp1, 1, Set1), + {ok, Set2} = update(DownstreamOp1, Set1), ?assertEqual([<<"foo">>], value(Set2)), - {ok, DownstreamOp2} = update({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set2), - {ok, Set3} = update(DownstreamOp2, 1, Set2), + {ok, DownstreamOp2} = generate_downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set2), + {ok, Set3} = update(DownstreamOp2, Set2), ?assertEqual([<<"foo">>, <<"li">>, <<"manu">>], value(Set3)), {_, {_, Token1}}=DownstreamOp1, @@ -250,50 +244,50 @@ value_test() -> remove_test() -> Set1 = new(), %% Add an element then remove it - {ok, Op1} = update({add, <<"foo">>}, 1, Set1), - {ok, Set2} = update(Op1, 1, Set1), + {ok, Op1} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, Set2} = update(Op1, Set1), ?assertEqual([<<"foo">>], value(Set2)), - {ok, Op2} = update({remove, <<"foo">>}, 1, Set2), - {ok, Set3} = update(Op2, 1, Set2), + {ok, Op2} = generate_downstream({remove, <<"foo">>}, 1, Set2), + {ok, Set3} = update(Op2, Set2), ?assertEqual([], value(Set3)), %% Add many elements then remove part - {ok, Op3} = update({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), - {ok, Set4} = update(Op3, 1, Set1), + {ok, Op3} = generate_downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), + {ok, Set4} = update(Op3, Set1), ?assertEqual([<<"foo">>, <<"li">>, <<"manu">>], value(Set4)), - {ok, Op5} = update({remove_all, [<<"foo">>, <<"li">>]},1 , Set4), - {ok, Set5} = update(Op5, 1, Set4), + {ok, Op5} = generate_downstream({remove_all, [<<"foo">>, <<"li">>]},1 , Set4), + {ok, Set5} = update(Op5, Set4), ?assertEqual([<<"manu">>], value(Set5)), %% Remove more than current have - {ok, Op6} = update({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), - {ok, Set6} = update(Op6, 1, Set1), - {ok, Op7} = update({remove_all, [<<"manu">>, <<"test">>]}, 1, Set6), - Result = update(Op7, 1, Set6), + {ok, Op6} = generate_downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), + {ok, Set6} = update(Op6, Set1), + {ok, Op7} = generate_downstream({remove_all, [<<"manu">>, <<"test">>]}, 1, Set6), + Result = update(Op7, Set6), ?assertEqual({error,{precondition,{not_present,<<"test">>}}}, Result). concurrent_add_test() -> Set1 = new(), %% Add an element then remove it - {ok, Op1} = update({add, <<"foo">>}, 1, Set1), - {ok, Set2} = update(Op1, 1, Set1), + {ok, Op1} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, Set2} = update(Op1, Set1), ?assertEqual([<<"foo">>], value(Set2)), %% If remove is concurrent with the second add, will not remove the second added - {ok, Op2} = update({remove, <<"foo">>}, 1, Set2), + {ok, Op2} = generate_downstream({remove, <<"foo">>}, 1, Set2), - {ok, Op3} = update({add, <<"foo">>}, 1, Set1), - {ok, Set3} = update(Op3, 1, Set2), + {ok, Op3} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, Set3} = update(Op3, Set2), ?assertEqual([<<"foo">>], value(Set3)), - {ok, Set4} = update(Op2, 1, Set3), + {ok, Set4} = update(Op2, Set3), ?assertEqual([<<"foo">>], value(Set4)), %% If remove follows two adds, remove will remove all - {ok, Op4} = update({remove, <<"foo">>}, 1, Set3), - {ok, Set5} = update(Op4, 1, Set3), + {ok, Op4} = generate_downstream({remove, <<"foo">>}, 1, Set3), + {ok, Set5} = update(Op4, Set3), ?assertEqual([], value(Set5)). binary_test() -> @@ -302,8 +296,8 @@ binary_test() -> ORSet2 = from_binary(BinaryORSet1), ?assert(equal(ORSet1, ORSet2)), - {ok, Op1} = update({add, <<"foo">>}, 1, ORSet1), - {ok, ORSet3} = update(Op1, 1, ORSet1), + {ok, Op1} = generate_downstream({add, <<"foo">>}, 1, ORSet1), + {ok, ORSet3} = update(Op1, ORSet1), BinaryORSet3 = to_binary(ORSet3), ORSet4 = from_binary(BinaryORSet3), ?assert(equal(ORSet3, ORSet4)). From 600c9644e63a366b2dd123ac51776249abe35401 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 24 Nov 2014 18:51:04 +0000 Subject: [PATCH 014/426] Add comments --- src/crdt_orset.erl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 53751767f..658058423 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -57,6 +57,11 @@ new() -> orddict:new(). +%% @doc +%% without parameter: return all existing elements in the `orset()' +%% {fragment, elem}: create and return a new `orset()' with all metadata +%% of an element +%% {tokens, elem}: returns all uniques tokens of an element in the set -spec value(orset()) -> [member()]. value(ORDict) -> orddict:fetch_keys(ORDict). @@ -79,6 +84,10 @@ value({tokens, Elem}, ORSet) -> value(_,ORSet) -> value(ORSet). +%% @doc generate downstream operations. +%% If the operation is add or add_all, generate unique tokens for each element +%% If the operation is remove or remove_all, fetches all unique tokens for +%% these elements existing in the `orset()'. -spec generate_downstream(orset_op(), actor(), orset()) -> {ok, orset_op()}. generate_downstream({add,Elem}, Actor, _ORDict) -> Token = unique(Actor), @@ -97,6 +106,13 @@ generate_downstream({remove_all,Elems}, _Actor, ORDict) -> {ok, {remove_all, ToRemove}}. +%% @doc apply downstream operations and update an `orset()'. +%% The first parameter denotes this operation is for adding or removing elements. +%% For add or add_all, the second element of the tuple is a list of elements and tokens to add +%% For remove or remove_all, the second element of the tuple is a list of elements and their tokens +%% to remove. +%% For update, the second element of the tuple is a list of updates to apply, each of which can +%% either be add, add_all or remove, remove_all. -spec update(orset_op(), orset()) -> {ok, orset()} | {error, {precondition ,{not_present, member()}}}. update({add, {Elem, [Token|_]}}, ORDict) -> @@ -139,7 +155,7 @@ precondition_context(ORDict) -> stats(ORSet) -> [ {S, stat(S, ORSet)} || S <- [element_count] ]. --spec stat(atom(), orset()) -> number() | undefined. +-spec stat(atom(), orset()) -> integer() | undefined. stat(element_count, ORSet) -> orddict:size(ORSet); stat(_, _) -> undefined. @@ -158,6 +174,7 @@ from_binary(<>) -> binary_to_term(Bin). %% Private +%% @doc add an element and its token to the `orset()'. add_elem(Elem,Token,ORDict) -> case orddict:find(Elem,ORDict) of {ok, Tokens} -> @@ -166,6 +183,7 @@ add_elem(Elem,Token,ORDict) -> {ok, orddict:store(Elem, [Token], ORDict)} end. +%% @doc remove all tokens of the element from the `orset()'. remove_elem({Elem,RemoveTokens},ORDict) -> case orddict:find(Elem,ORDict) of {ok, Tokens} -> @@ -196,6 +214,7 @@ apply_ops([Op | Rest], ORDict) -> Error -> Error end. +%% @doc generate a unique identifier (best-effort). unique(_Actor) -> crypto:strong_rand_bytes(20). From 2231c0267dc92efea40c87eb93ad2767a3821bdd Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 24 Nov 2014 23:37:04 +0000 Subject: [PATCH 015/426] Finish test --- src/crdt_orset.erl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 658058423..7640829c1 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -178,7 +178,12 @@ from_binary(<>) -> add_elem(Elem,Token,ORDict) -> case orddict:find(Elem,ORDict) of {ok, Tokens} -> - {ok, orddict:store(Elem, Tokens++[Token], ORDict)}; + case lists:member(Token, Tokens) of + true -> + {ok, ORDict}; + false -> + {ok, orddict:store(Elem, Tokens++[Token], ORDict)} + end; error -> {ok, orddict:store(Elem, [Token], ORDict)} end. From 058c0b92ca12940082734cec8f24a9d8a27056ed Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 2 Dec 2014 16:01:49 +0000 Subject: [PATCH 016/426] Fix error condition in orset --- src/crdt_orset.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 7640829c1..8c795dd83 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -200,7 +200,12 @@ remove_elem({Elem,RemoveTokens},ORDict) -> {ok, orddict:store(Elem, Tokens--RemoveTokens, ORDict)} end; error -> - {error, {precondition, {not_present, Elem}}} + case RemoveTokens of + [] -> + {ok, ORDict}; + _ -> + {error, {precondition, {not_present, Elem}}} + end end. remove_elems([], ORDict) -> @@ -289,7 +294,7 @@ remove_test() -> {ok, Set6} = update(Op6, Set1), {ok, Op7} = generate_downstream({remove_all, [<<"manu">>, <<"test">>]}, 1, Set6), Result = update(Op7, Set6), - ?assertEqual({error,{precondition,{not_present,<<"test">>}}}, Result). + ?assertMatch({ok, _}, Result). concurrent_add_test() -> From fa741a838d77175dc6a1480514bdfcc1c846adb5 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 12 Jan 2015 18:58:51 +0000 Subject: [PATCH 017/426] Add info and change to new CRDTs --- src/crdt_orset.erl | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 8c795dd83..0d1960ac9 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -1,6 +1,6 @@ %% ------------------------------------------------------------------- %% -%% crdt_orset: A convergent, replicated, state based observe remove set +%% crdt_orset: A convergent, replicated, operation based observe remove set %% %% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. %% @@ -20,8 +20,28 @@ %% %% ------------------------------------------------------------------- --module(crdt_orset). +%% @doc +%% An operation-based Observed-Remove Set CRDT. +%% As the data structure is operation-based, to issue an operation, one should firstly call +%% `generate_downstream/3' to get the downstream version of the operation and then call `update/2'. +%% +%% It provides five operations: add, which adds an element to a set; add_all, adds a list of elements +%% to a set; remove, which removes an element from a set; remove_all that removes a list of elements +%% from the set; update, that contains a list of previous four commands. +%% +%% This file is adapted from riak_dt_orset, a state-based implementation of Observed-Remove Set. +%% The changes are as follows: +%% 1. `generate_downstream/3' is added, as this is necessary for op-based CRDTs. +%% 2. `merge/2' is removed. +%% 3. There is no tombstone of removed elements. +%% +%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of +%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ +%% +%% @end + +-module(crdt_orset). %% API -export([new/0, value/1, generate_downstream/3, update/2, equal/2, @@ -46,7 +66,6 @@ -type binary_orset() :: binary(). %% A binary that from_binary/1 will operate on. -type orset_op() :: {add, member()} | {remove, member()} | - {get_downstream, member()}| {add_all, [member()]} | {remove_all, [member()]} | {update, [orset_op()]}. From 787ba3665be3b079fdd2c97142b72a4fec170752 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 13 Jan 2015 10:49:05 +0000 Subject: [PATCH 018/426] Adjust line length --- src/crdt_orset.erl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 0d1960ac9..0f8296679 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -22,14 +22,17 @@ %% @doc %% An operation-based Observed-Remove Set CRDT. -%% As the data structure is operation-based, to issue an operation, one should firstly call -%% `generate_downstream/3' to get the downstream version of the operation and then call `update/2'. +%% As the data structure is operation-based, to issue an operation, one should +%% firstly call `generate_downstream/3' to get the downstream version of the +%% operation and then call `update/2'. %% -%% It provides five operations: add, which adds an element to a set; add_all, adds a list of elements -%% to a set; remove, which removes an element from a set; remove_all that removes a list of elements -%% from the set; update, that contains a list of previous four commands. +%% It provides five operations: add, which adds an element to a set; add_all, +%% adds a list of elements to a set; remove, which removes an element from a set; +%% remove_all that removes a list of elements from the set; update, that contains +%% a list of previous four commands. %% -%% This file is adapted from riak_dt_orset, a state-based implementation of Observed-Remove Set. +%% This file is adapted from riak_dt_orset, a state-based implementation of +%% Observed-Remove Set. %% The changes are as follows: %% 1. `generate_downstream/3' is added, as this is necessary for op-based CRDTs. %% 2. `merge/2' is removed. From 3be92c6cb289ade8446c446aaaced96709723d50 Mon Sep 17 00:00:00 2001 From: Christopher Meiklejohn Date: Mon, 12 Jan 2015 11:55:50 -0500 Subject: [PATCH 019/426] Fix build. Resolve problems in the build where under a defined EQC compile, it would attempt to export functions which were removed from the module. --- src/crdt_orset.erl | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 0f8296679..dbdd67230 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -42,27 +42,16 @@ %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% %% @end - - -module(crdt_orset). %% API -export([new/0, value/1, generate_downstream/3, update/2, equal/2, to_binary/1, from_binary/1, value/2, precondition_context/1, stats/1, stat/2]). --ifdef(EQC). --include_lib("eqc/include/eqc.hrl"). --endif. - -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. -%% EQC API --ifdef(EQC). --export([init_state/0, gen_op/0, update_expected/3, eqc_state_value/1]). --endif. - -export_type([orset/0, binary_orset/0, orset_op/0]). -opaque orset() :: orddict:orddict(). From 565052b175b72ce87a3f8caaf968ce5e8f9aa02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sat, 6 Jun 2015 21:50:06 +0300 Subject: [PATCH 020/426] Use "include_lib" instead of "include ../deps/" --- src/crdt_orset.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index dbdd67230..71aa0b487 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -171,7 +171,7 @@ stat(element_count, ORSet) -> orddict:size(ORSet); stat(_, _) -> undefined. --include("../deps/riak_dt/include/riak_dt_tags.hrl"). +-include_lib("riak_dt/include/riak_dt_tags.hrl"). -define(TAG, ?DT_ORSET_TAG). -define(V1_VERS, 1). From 0928cc6e7710f0c1e87a03c7ab4a656c27365349 Mon Sep 17 00:00:00 2001 From: "Alejandro Z. Tomsic" Date: Thu, 17 Sep 2015 18:25:16 +0200 Subject: [PATCH 021/426] changed certification --- src/crdt_orset.erl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/crdt_orset.erl b/src/crdt_orset.erl index 71aa0b487..6f82f71c0 100644 --- a/src/crdt_orset.erl +++ b/src/crdt_orset.erl @@ -46,7 +46,7 @@ %% API -export([new/0, value/1, generate_downstream/3, update/2, equal/2, - to_binary/1, from_binary/1, value/2, precondition_context/1, stats/1, stat/2]). + to_binary/1, from_binary/1, value/2, precondition_context/1, stats/1, stat/2, is_operation/1]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -244,6 +244,12 @@ minimum_tokens(Tokens) -> not Removed end, Tokens). +%% @doc The following operation verifies +%% that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(Operation) -> + riak_dt_orset:is_operation(Operation). + %% =================================================================== %% EUnit tests %% =================================================================== From 8ed908b1dd121588cfb3ef33a40dc4581183dc11 Mon Sep 17 00:00:00 2001 From: Diogo Serra Date: Sun, 11 Jan 2015 21:44:17 +0000 Subject: [PATCH 022/426] Added bounded counter CRDT. Also fixed error handling in transactions and downstream generation, as well as rename to Antidote in riak_test setup instructions. --- src/crdt_bcounter.erl | 259 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 src/crdt_bcounter.erl diff --git a/src/crdt_bcounter.erl b/src/crdt_bcounter.erl new file mode 100644 index 000000000..07324ed78 --- /dev/null +++ b/src/crdt_bcounter.erl @@ -0,0 +1,259 @@ +%% -*- coding: utf-8 -*- +%% -------------------------------------------------------------------------- +%% +%% crdt_bcounter: A convergent, replicated, operation based bounded counter. +%% +%% -------------------------------------------------------------------------- + +%% @doc +%% An operation based implementation of the bounded counter CRDT. +%% This counter is able to maintain a non-negative value by +%% explicitly exchanging permissions to execute decrement operations. +%% All operations on this CRDT are monotonic and do not keep extra tombstones. +%% @end + +-module(crdt_bcounter). + +%% API +-export([new/0, + localPermissions/2, + permissions/1, + value/1, + generate_downstream/3, + update/2, + to_binary/1, + from_binary/1]). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-export_type([bcounter/0, binary_bcounter/0, bcounter_op/0, id/0]). + +-opaque bcounter() :: {orddict:orddict(),orddict:orddict()}. +-type binary_bcounter() :: binary(). +-type bcounter_op() :: bcounter_anon_op() | bcounter_src_op(). +-type bcounter_anon_op() :: {transfer, pos_integer(), id()} | + {increment, pos_integer()} | {decrement, pos_integer()}. +-type bcounter_src_op() :: {bcounter_anon_op(), id()}. +-opaque id() :: term. %% A replica's identifier. + +%% @doc Return a new, empty `bcounter()'. +-spec new() -> bcounter(). +new() -> + {orddict:new(),orddict:new()}. + +%% @doc Return the available permissions of replica `Id' in a `bcounter()'. +-spec localPermissions(id(),bcounter()) -> non_neg_integer(). +localPermissions(Id,{P,D}) -> + Received = lists:foldl( + fun( + {_,V},Acc) -> + Acc + V + end, + 0, orddict:filter( + fun( + {_,To},_) when To == Id -> + true; + (_,_) -> + false + end, P)), + Granted = lists:foldl( + fun + ({_,V},Acc) -> + Acc + V + end, 0, orddict:filter( + fun + ({From,To},_) when From == Id andalso To /= Id -> + true; + (_,_) -> + false + end, P)), + case orddict:find(Id,D) of + {ok, Decrements} -> + Received - Granted - Decrements; + error -> + Received - Granted + end. + +%% @doc Return the total available permissions in a `bcounter()'. +-spec permissions(bcounter()) -> non_neg_integer(). +permissions({P,D}) -> + TotalIncrements = orddict:fold( + fun + ({K,K},V,Acc) -> + V + Acc; + (_,_,Acc) -> + Acc + end, 0, P), + TotalDecrements = orddict:fold( + fun + (_,V,Acc) -> + V + Acc + end, 0, D), + TotalIncrements - TotalDecrements. + +%% @doc Return the read value of a given `bcounter()', itself. +-spec value(bcounter()) -> bcounter(). +value(Counter) -> Counter. + +%% @doc Generate a downstream operation. +%% The first parameter is either `{increment, pos_integer()}' or `{decrement, pos_integer()}', +%% which specify the operation and amount, or `{transfer, pos_integer(), id()}' +%% that additionally specifies the target replica. +%% The second parameter is an `actor()' who identifies the source replica, +%% and the third parameter is a `bcounter()' which holds the current snapshot. +%% +%% Return a tuple containing the operation and source replica. +%% This operation fails and returns `{error, no_permissions}' +%% if it tries to consume resources unavailable to the source replica +%% (which prevents logging of forbidden attempts). +-spec generate_downstream(bcounter_op(), riak_dt:actor(), bcounter()) -> {ok, bcounter_op()}. +generate_downstream({increment,V}, Actor, _Counter) when is_integer(V), V > 0 -> + {ok, {{increment,V},Actor}}; +generate_downstream({decrement,V}, Actor, Counter) when is_integer(V), V > 0 -> + generate_downstream_check({decrement,V}, Actor, Counter, V); +generate_downstream({transfer,V,To}, Actor, Counter) when is_integer(V), V > 0 -> + generate_downstream_check({transfer,V,To}, Actor, Counter, V). + +generate_downstream_check(Op, Actor, Counter, V) -> + Available = localPermissions(Actor, Counter), + if Available >= V -> {ok, {Op,Actor}}; + Available < V -> {error, no_permissions} + end. + +%% @doc Update a `bcounter()' with a downstream operation, +%% usually created with `generate_downstream'. +%% +%% Return the resulting `bcounter()' after applying the operation. +-spec update(bcounter_op(), bcounter()) -> {ok, bcounter()}. +update({{increment, V},Id}, Counter) -> + increment(Id,V,Counter); +update({{decrement, V},Id}, Counter) -> + decrement(Id,V,Counter); +update({{transfer, V,To},From}, Counter) -> + transfer(From,To,V,Counter). + +%% Add a given amount of permissions to a replica. +increment(Id,V,{P,D}) -> + {ok,{orddict:update_counter({Id,Id},V,P),D}}. + +%% Consume a given amount of permissions from a replica. +decrement(Id,V,{P,D}) -> + {ok, {P,orddict:update_counter(Id,V,D)}}. + +%% Transfer a given amount of permissions from one replica to another. +transfer(From,To,V,{P,D}) -> + {ok, {orddict:update_counter({From,To},V,P),D}}. + +%% doc Return the binary representation of a `bcounter()'. +-spec to_binary(bcounter()) -> binary(). +to_binary(C) -> term_to_binary(C). + +%% doc Return a `bcounter()' from its binary representation. +-spec from_binary(binary()) -> bcounter(). +from_binary(<>) -> binary_to_term(B). + +%% =================================================================== +%% EUnit tests +%% =================================================================== + +-ifdef(TEST). + +%% Utility to generate and apply downstream operations. +apply_op(Op, Actor, Counter) -> + {ok, OP_DS} = generate_downstream(Op, Actor, Counter), + {ok, NewCounter} = update(OP_DS, Counter), + NewCounter. + +%% Tests creating a new `bcounter()'. +new_test() -> + ?assertEqual({[],[]}, new()). + +%% Tests increment operations. +increment_test() -> + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter2 = apply_op({increment, 5}, r2, Counter1), + %% Test replicas' values. + ?assertEqual(5, localPermissions(r2,Counter2)), + ?assertEqual(10, localPermissions(r1,Counter2)), + %% Test total value. + ?assertEqual(15, permissions(Counter2)). + +%% Tests the function `localPermissions()'. +localPermisisons_test() -> + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + %% Test replica with positive amount of permissions. + ?assertEqual(10, localPermissions(r1,Counter1)), + %% Test nonexistent replica. + ?assertEqual(0, localPermissions(r2,Counter1)). + +%% Tests decrement operations. +decrement_test() -> + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + %% Test allowed decrement. + Counter2 = apply_op({decrement, 6}, r1, Counter1), + ?assertEqual(4, permissions(Counter2)), + %% Test nonexistent replica. + ?assertEqual(0, localPermissions(r2,Counter1)), + %% Test forbidden decrement. + OP_DS = generate_downstream({decrement, 6}, r1, Counter2), + ?assertEqual({error,no_permissions}, OP_DS). + +%% Tests a more complex chain of increment and decrement operations. +decrement_increment_test() -> + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter2 = apply_op({decrement, 6}, r1, Counter1), + Counter3 = apply_op({increment, 6}, r2, Counter2), + %% Test several replicas (balance each other). + ?assertEqual(10, permissions(Counter3)), + %% Test forbidden permissions, when total is higher than consumed. + OP_DS = generate_downstream({decrement, 6}, r1, Counter3), + ?assertEqual({error,no_permissions}, OP_DS), + %% Test the same operation is allowed on another replica with enough permissions. + Counter4 = apply_op({decrement, 6}, r2, Counter3), + ?assertEqual(4, permissions(Counter4)). + +%% Tests transferring permissions. +transfer_test() -> + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + %% Test transferring permissions from one replica to another. + Counter2 = apply_op({transfer, 6, r2}, r1, Counter1), + ?assertEqual(4, localPermissions(r1,Counter2)), + ?assertEqual(6, localPermissions(r2,Counter2)), + ?assertEqual(10, permissions(Counter2)), + %% Test transference forbidden by lack of previously transfered resources. + OP_DS = generate_downstream({transfer, 5, r2}, r1, Counter2), + ?assertEqual({error,no_permissions}, OP_DS), + %% Test transference enabled by previously transfered resources. + Counter3 = apply_op({transfer, 5, r1}, r2, Counter2), + ?assertEqual(9, localPermissions(r1,Counter3)), + ?assertEqual(1, localPermissions(r2,Counter3)), + ?assertEqual(10, permissions(Counter3)). + +%% Tests the function `value()'. +value_test() -> + %% Test on `bcounter()' resulting from applying all kinds of operation. + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter2 = apply_op({decrement, 6}, r1, Counter1), + Counter3 = apply_op({transfer, 2, r2}, r1, Counter2), + %% Assert `value()' returns `bcounter()' itself. + ?assertEqual(Counter3, value(Counter3)). + +%% Tests serialization functions `to_binary()' and `from_binary()'. +binary_test() -> + %% Test on `bcounter()' resulting from applying all kinds of operation. + Counter0 = new(), + Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter2 = apply_op({decrement, 6}, r1, Counter1), + Counter3 = apply_op({transfer, 2, r2}, r1, Counter2), + %% Assert marshaling and unmarshaling holds the same `bcounter()'. + B = to_binary(Counter3), + ?assertEqual(Counter3, from_binary(B)). +-endif. \ No newline at end of file From 5fa2aa647a59594d1bb42f1eeb67366df570fd4d Mon Sep 17 00:00:00 2001 From: Diogo Serra Date: Wed, 21 Jan 2015 17:39:28 +0000 Subject: [PATCH 023/426] Fix crdt_bcounter:generate_downstream return type. --- src/crdt_bcounter.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crdt_bcounter.erl b/src/crdt_bcounter.erl index 07324ed78..73fcf0663 100644 --- a/src/crdt_bcounter.erl +++ b/src/crdt_bcounter.erl @@ -108,7 +108,7 @@ value(Counter) -> Counter. %% This operation fails and returns `{error, no_permissions}' %% if it tries to consume resources unavailable to the source replica %% (which prevents logging of forbidden attempts). --spec generate_downstream(bcounter_op(), riak_dt:actor(), bcounter()) -> {ok, bcounter_op()}. +-spec generate_downstream(bcounter_op(), riak_dt:actor(), bcounter()) -> {ok, bcounter_op()} | {error, no_permissions}. generate_downstream({increment,V}, Actor, _Counter) when is_integer(V), V > 0 -> {ok, {{increment,V},Actor}}; generate_downstream({decrement,V}, Actor, Counter) when is_integer(V), V > 0 -> From 11c37fb433ad65c421701976e982a27a917de22b Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 23 Jan 2015 12:05:24 +0100 Subject: [PATCH 024/426] add readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..f6c308be5 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +antidote_pb +========= + +Erlang client for antiodote protocol buffer interface \ No newline at end of file From 01e447e88b30379a7423f7b8b395912ce356b412 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 23 Jan 2015 12:09:46 +0100 Subject: [PATCH 025/426] antidote_pb client files; taken from antidote --- Makefile | 137 ++++++++++++++++++ rebar | Bin 0 -> 160323 bytes rebar.config | 11 ++ src/antidote_pb.app.src | 11 ++ src/antidotec_counter.erl | 103 ++++++++++++++ src/antidotec_datatype.erl | 85 +++++++++++ src/antidotec_pb_socket.erl | 275 ++++++++++++++++++++++++++++++++++++ src/antidotec_set.erl | 159 +++++++++++++++++++++ 8 files changed, 781 insertions(+) create mode 100644 Makefile create mode 100755 rebar create mode 100644 rebar.config create mode 100644 src/antidote_pb.app.src create mode 100644 src/antidotec_counter.erl create mode 100644 src/antidotec_datatype.erl create mode 100644 src/antidotec_pb_socket.erl create mode 100644 src/antidotec_set.erl diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..de08aceba --- /dev/null +++ b/Makefile @@ -0,0 +1,137 @@ +# Copyright 2012 Erlware, LLC. All Rights Reserved. +# +# This file is provided to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +ERLFLAGS= -pa $(CURDIR)/.eunit -pa $(CURDIR)/ebin -pa $(CURDIR)/deps/*/ebin + +DEPS_PLT=$(CURDIR)/.deps_plt +DEPS=erts kernel stdlib + +# ============================================================================= +# Verify that the programs we need to run are installed on this system +# ============================================================================= +ERL = $(shell which erl) + +ifeq ($(ERL),) +$(error "Erlang not available on this system") +endif + +# REBAR=$(shell which rebar) +# ifeq ($(REBAR),) +# $(error "Rebar not available on this system") +# endif + +REBAR=./rebar + + +.PHONY: all compile doc clean test dialyzer typer shell distclean pdf \ + update-deps clean-common-test-data rebuild + +all: deps compile test + +# ============================================================================= +# Rules to build the system +# ============================================================================= + +deps: + $(REBAR) get-deps + $(REBAR) compile + +update-deps: + $(REBAR) update-deps + $(REBAR) compile + +compile: + $(REBAR) skip_deps=true compile + +doc: + $(REBAR) skip_deps=true doc + +eunit: compile clean-common-test-data + $(REBAR) skip_deps=true eunit + +$(TEST_DEPS): + @echo Running EUnit + +test: compile eunit + +PLT ?= $(HOME)/.combo_dialyzer_plt +LOCAL_PLT = .local_dialyzer_plt +DIALYZER_FLAGS ?= -Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspecs + +${PLT}: compile + @if [ -f $(PLT) ]; then \ + dialyzer --check_plt --plt $(PLT) && \ + dialyzer --add_to_plt --plt $(PLT) --output_plt $(PLT) ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(PLT) ; test $$? -ne 1; \ + fi + +${LOCAL_PLT}: compile + @if [ -d deps ]; then \ + if [ -f $(LOCAL_PLT) ]; then \ + dialyzer --check_plt --plt $(LOCAL_PLT) deps/*/ebin && \ + dialyzer --add_to_plt --plt $(LOCAL_PLT) --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + fi \ + fi + +dialyzer: ${PLT} ${LOCAL_PLT} + @echo "==> $(shell basename $(shell pwd)) (dialyzer)" + @if [ -f $(LOCAL_PLT) ]; then \ + PLTS="$(PLT) $(LOCAL_PLT)"; \ + else \ + PLTS=$(PLT); \ + fi; \ + if [ -f dialyzer.ignore-warnings ]; then \ + if [ $$(grep -cvE '[^[:space:]]' dialyzer.ignore-warnings) -ne 0 ]; then \ + echo "ERROR: dialyzer.ignore-warnings contains a blank/empty line, this will match all messages!"; \ + exit 1; \ + fi; \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin > dialyzer_warnings ; \ + egrep -v "^[[:space:]]*(done|Checking|Proceeding|Compiling)" dialyzer_warnings | grep -F -f dialyzer.ignore-warnings -v > dialyzer_unhandled_warnings ; \ + cat dialyzer_unhandled_warnings ; \ + [ $$(cat dialyzer_unhandled_warnings | wc -l) -eq 0 ] ; \ + else \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin; \ + fi + +typer: + typer --plt $(DEPS_PLT) -r ./src + +shell: deps compile +# You often want *rebuilt* rebar tests to be available to the +# shell you have to call eunit (to get the tests +# rebuilt). However, eunit runs the tests, which probably +# fails (thats probably why You want them in the shell). This +# runs eunit but tells make to ignore the result. + - @$(REBAR) skip_deps=true eunit + @$(ERL) $(ERLFLAGS) + +clean: + - rm -rf $(CURDIR)/test/*.beam + - rm -rf $(CURDIR)/logs + - rm -rf $(CURDIR)/ebin + $(REBAR) skip_deps=true clean + +distclean: clean + - rm -rf $(DEPS_PLT) + - rm -rvf $(CURDIR)/deps + +rebuild: distclean deps compile escript dialyzer test + + diff --git a/rebar b/rebar new file mode 100755 index 0000000000000000000000000000000000000000..14e5c22455662c4eb3752852b9e436dda1d5b6e9 GIT binary patch literal 160323 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
}Xe^QK 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 bXULGC>7fQ+04S6?_(#7P?3{r{DAfM|j}GYJ literal 0 HcmV?d00001 diff --git a/rebar.config b/rebar.config new file mode 100644 index 000000000..f242d5a37 --- /dev/null +++ b/rebar.config @@ -0,0 +1,11 @@ +{lib_dirs,["deps"]}. +{sub_dirs, ["rel"]}. + +{deps, [ + {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "2.0.3"}}}, + {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {tag, "antidote"}}} +]}. + +{erl_opts, [debug_info, warnings_as_errors, {parse_transform, lager_transform}]}. +{cover_enabled, true}. +{eunit_opts, [verbose, {report, {eunit_surefire, [{dir,"."}]}}]}. \ No newline at end of file diff --git a/src/antidote_pb.app.src b/src/antidote_pb.app.src new file mode 100644 index 000000000..418ac4485 --- /dev/null +++ b/src/antidote_pb.app.src @@ -0,0 +1,11 @@ +{application, antidote_pb, + [ + {description, "Protocol Buffer client for antidote"}, + {vsn, "1"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {env, []} + ]}. diff --git a/src/antidotec_counter.erl b/src/antidotec_counter.erl new file mode 100644 index 000000000..ba70a73f7 --- /dev/null +++ b/src/antidotec_counter.erl @@ -0,0 +1,103 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- +-module(antidotec_counter). + +-include_lib("riak_pb/include/antidote_pb.hrl"). + +-behaviour(antidotec_datatype). + +-export([new/1, + new/2, + message_for_get/1, + value/1, + to_ops/1, + is_type/1, + type/0, + dirty_value/1 + ]). + +-export([increment/1, + increment/2, + decrement/1, + decrement/2 + ]). + +-record(counter, { + key :: term(), + value :: integer(), + increment :: integer() + }). + +-export_type([antidote_counter/0]). +-opaque antidote_counter() :: #counter{}. + +-spec new(term()) -> antidote_counter(). +new(Key) -> + #counter{key=Key, value=0, increment=0}. + +-spec new(term(), integer()) -> antidote_counter(). +new(Key, Value) -> + #counter{key=Key, value=Value, increment=0}. + +-spec value(antidote_counter()) -> integer(). +value(#counter{value=Value}) -> + Value. + +-spec dirty_value(antidote_counter()) -> integer(). +dirty_value(#counter{value=Value, increment=Increment}) -> + Value + Increment. + +%% @doc Increments the counter with 1 unit. +-spec increment(antidote_counter()) -> antidote_counter(). +increment(Counter) -> + increment(1, Counter). + +%% @doc Increments the counter with Amount units. +-spec increment(integer(), antidote_counter()) -> antidote_counter(). +increment(Amount, #counter{increment=Value}=Counter) when is_integer(Amount) -> + Counter#counter{increment=Value+Amount}. + +%% @doc Decrements the counter by 1. +-spec decrement(antidote_counter()) -> antidote_counter(). +decrement(Counter) -> + increment(-1, Counter). + +%% @doc Decrements the counter by the passed amount. +-spec decrement(integer(), antidote_counter()) -> antidote_counter(). +decrement(Amount, #counter{increment=Value}=Counter) -> + Counter#counter{increment=Value-Amount}. + +-spec is_type(term()) -> boolean(). +is_type(T) -> + is_record(T, counter). + +-spec type() -> riak_dt_pncounter. +type() -> riak_dt_pncounter. + +to_ops(#counter{key=_Key, increment=0}) -> undefined; + +to_ops(#counter{key=Key, increment=Amount}) when Amount < 0 -> + [#fpbdecrementreq{key=Key, amount=-Amount}]; + +to_ops(#counter{key=Key, increment=Amount}) -> + [#fpbincrementreq{key=Key, amount=Amount}]. + +message_for_get(Key) -> #fpbgetcounterreq{key=Key}. + diff --git a/src/antidotec_datatype.erl b/src/antidotec_datatype.erl new file mode 100644 index 000000000..c58da3ba6 --- /dev/null +++ b/src/antidotec_datatype.erl @@ -0,0 +1,85 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- +-module(antidotec_datatype). + +-ifdef(EQC). +-include_lib("eqc/include/eqc.hrl"). +-include_lib("eunit/include/eunit.hrl"). +-define(QC_OUT(P), eqc:on_output(fun(Fmt, Args) -> io:format(user, Fmt, Args) end, P)). +-compile(export_all). +-endif. + + +-define(MODULES, [antidotec_counter, antidotec_set]). + +-export([module_for_type/1, + module_for_term/1]). + +-export_type([datatype/0, update/0]). + +-type maybe(T) :: T | undefined. +-type datatype() :: term(). +-type typename() :: atom(). +-type update() :: [term()]. + +%% @doc Constructs a new container for the type with the specified +%% value and key. This should only be used internally by the client code. +-callback new(Key::binary(), Value::term()) -> datatype(). + +%% @doc Returns the original, unmodified value of the object. This does +%% not include the execution of any locally-queued operations. +-callback value(datatype()) -> term(). + +%% @doc Returns the local value of the object, with the local operations applied. +-callback dirty_value(datatype()) -> term(). + +%% @doc Returns the message to get an object of the type of this container. +-callback message_for_get(binary()) -> term(). + +%% @doc Extracts the list of operations to be append to the object's log. +%% 'undefined' should be returned if the type is unmodified. +-callback to_ops(datatype()) -> update(). + +%% @doc Determines whether the given term is the type managed by the +%% container module. +-callback is_type(datatype()) -> boolean(). + +%% @doc Determines the symbolic name of the container's type, e.g. +%% antidote_set, antidote_map, antidote_counter. +-callback type() -> typename(). + +%% @doc Returns the module name for the container of the given CRDT data-type. +-spec module_for_type(riak_dt_orset | riak_dt_pncounter) -> + antidotec_counter | antidotec_set. +module_for_type(riak_dt_orset) -> antidotec_set; +module_for_type(riak_dt_pncounter) -> antidotec_counter. + +%% @doc Returns the container module name for the given term. +%% Returns undefined if the module is not known. +-spec module_for_term(datatype()) -> maybe(module()). +module_for_term(T) -> + lists:foldl(fun(Mod, undefined) -> + case Mod:is_type(T) of + true -> Mod; + false -> undefined + end; + (_, Mod) -> + Mod + end, undefined, ?MODULES). diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl new file mode 100644 index 000000000..82f8dab8f --- /dev/null +++ b/src/antidotec_pb_socket.erl @@ -0,0 +1,275 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- +-module(antidotec_pb_socket). + +-include_lib("riak_pb/include/antidote_pb.hrl"). + +-behaviour(gen_server). + +-define(FIRST_RECONNECT_INTERVAL, 100). +-define(TIMEOUT, 1000). + +%% The TCP/IP host name or address of the Riak node +-type address() :: string() | atom() | inet:ip_address(). + %% The TCP port number of the Riak node's Protocol Buffers interface +-type portnum() :: non_neg_integer(). +-type msg_id() :: non_neg_integer(). +-type rpb_req() :: {tunneled, msg_id(), binary()} | atom() | tuple(). + +-record(request, {ref :: reference(), msg :: rpb_req(), from, timeout :: timeout(), + tref :: reference() | undefined }). + +-record(state, { + address :: address(), % address to connect to + port :: portnum(), % port to connect to + sock :: port(), % gen_tcp socket + active :: #request{} | undefined, % active request + connect_timeout=infinity :: timeout(), % timeout of TCP connection + keepalive = false :: boolean() % if true, enabled TCP keepalive for the socket + }). + +-export([start_link/2, start_link/3, + start/2, start/3, + stop/1, + handle_call/3, + handle_info/2, + handle_cast/2, + init/1, + code_change/3, + terminate/2]). + +-export([ + store_crdt/2, + get_crdt/3 + ]). + +%% @private +init([Address, Port, _Options]) -> + State = #state{address = Address, port = Port, active = undefined}, + case connect(State) of + {error, Reason} -> + {stop, {tcp, Reason}}; + Ok -> Ok + end. + +%% @doc Create a linked process to talk with the riak server on Address:Port +%% Client id will be assigned by the server. +-spec start_link(address(), portnum()) -> {ok, pid()} | {error, term()}. +start_link(Address, Port) -> + start_link(Address, Port, []). + +%% @doc Create a linked process to talk with the riak server on Address:Port with Options. +%% Client id will be assigned by the server. +start_link(Address, Port, Options) when is_list(Options) -> + gen_server:start_link(?MODULE, [Address, Port, Options], []). + +%% @doc Create a process to talk with the riak server on Address:Port. +%% Client id will be assigned by the server. +start(Address, Port) -> + start(Address, Port, []). + +%% @doc Create a process to talk with the riak server on Address:Port with Options. +start(Address, Port, Options) when is_list(Options) -> + gen_server:start(?MODULE, [Address, Port, Options], []). + +%% @doc Disconnect the socket and stop the process. +stop(Pid) -> + call_infinity(Pid, stop). + +%% @private Like `gen_server:call/3', but with the timeout hardcoded +%% to `infinity'. +call_infinity(Pid, Msg) -> + gen_server:call(Pid, Msg, infinity). + +%% @private +handle_call({req, Msg, Timeout}, From, State) -> + {noreply, send_request(new_request(Msg, From, Timeout), State)}; + +handle_call(stop, _From, State) -> + _ = disconnect(State), + {stop, normal, ok, State}. + +%% @private +%% @todo handle timeout +handle_info({_Proto, Sock, Data}, State=#state{active = (Active = #request{})}) -> + <> = Data, + Resp = riak_pb_codec:decode(MsgCode, MsgData), + NewState = case Resp of + %Must abstract message handling + #fpboperationresp{success = true} -> + cancel_req_timer(Active#request.tref), + _ = send_caller(ok, Active), + State#state{ active = undefined }; + #fpbgetcounterresp{value = Val} -> + cancel_req_timer(Active#request.tref), + _ = send_caller({ok,Val}, Active), + State#state{ active = undefined }; + #fpbgetsetresp{value = Val} -> + cancel_req_timer(Active#request.tref), + _ = send_caller({ok,erlang:binary_to_term(Val)}, Active), + State#state{ active = undefined }; + _ -> + lager:warning("Unexpected Message ~p",[Resp]), + State#state{ active = undefined } + end, + ok = inet:setopts(Sock, [{active, once}]), + {noreply, NewState}; + +handle_info({req_timeout, _Ref}, State=#state{active = Active}) -> + cancel_req_timer(Active#request.tref), + _ = send_caller({error, timeout}, Active), + {noreply, State#state{ active = undefined }}; + +handle_info({tcp_closed, _Socket}, State) -> + disconnect(State); + +handle_info({_Proto, Sock, _Data}, State) -> + ok = inet:setopts(Sock, [{active, once}]), + {noreply, State}. + +%% @private +handle_cast(_Msg, State) -> + {noreply, State}. + +%% @private +terminate(_Reason, _State) -> ok. + +%% @private +code_change(_OldVsn, State, _Extra) -> {ok, State}. + +%% @private +%% Connect the socket if disconnected +connect(State) when State#state.sock =:= undefined -> + #state{address = Address, port = Port} = State, + case gen_tcp:connect(Address, Port, + [binary, {active, once}, {packet, 4}, + {keepalive, State#state.keepalive}], + State#state.connect_timeout) of + {ok, Sock} -> + {ok, State#state{sock = Sock}}; + Error -> Error + end. + + +disconnect(State) -> + %% Tell any pending requests we've disconnected + _ = case State#state.active of + undefined -> + ok; + Request -> + send_caller({error, disconnected}, Request) + end, + + %% Make sure the connection is really closed + case State#state.sock of + undefined -> + ok; + Sock -> + gen_tcp:close(Sock) + end, + NewState = State#state{sock = undefined, active = undefined}, + {stop, disconnected, NewState}. + + +%% @private +new_request(Msg, From, Timeout) -> + Ref = make_ref(), + #request{ref = Ref, msg = Msg, from = From, timeout = Timeout, + tref = create_req_timer(Timeout, Ref)}. + +%% @private +%% Create a request timer if desired, otherwise return undefined. +create_req_timer(infinity, _Ref) -> + undefined; +create_req_timer(undefined, _Ref) -> + undefined; +create_req_timer(Msecs, Ref) -> + erlang:send_after(Msecs, self(), {req_timeout, Ref}). + +%% Send a request to the server and prepare the state for the response +%% @private +send_request(Request0, State) when State#state.active =:= undefined -> + {Request, Pkt} = encode_request_message(Request0), + case gen_tcp:send(State#state.sock, Pkt) of + ok -> + maybe_reply({noreply,State#state{active = Request}}); + {error, Reason} -> + lager:warning("Socket error while sending riakc request: ~p.", [Reason]), + gen_tcp:close(State#state.sock) + end. + +%% Unencoded Request (the normal PB client path) +encode_request_message(#request{msg=Msg}=Req) -> + {Req, riak_pb_codec:encode(Msg)}. + +%maybe_reply({reply, Reply, State = #state{active = Request}}) -> +% NewRequest = send_caller(Reply, Request), +% State#state{active = NewRequest}; + +maybe_reply({noreply, State = #state{}}) -> + State. + + +% Replies the message and clears the requester id +send_caller(Msg, #request{from = From}=Request) when From /= undefined -> + gen_server:reply(From, Msg), + Request#request{from = undefined}. + +%% @private +%% Cancel a request timer made by create_timer/2 +cancel_req_timer(undefined) -> + ok; +cancel_req_timer(Tref) -> + _ = erlang:cancel_timer(Tref), + ok. + +%Stores a client-side crdt to the storage by converting the object state to a +%list of oeprations that will be appended to the log. +%% @todo: propagate only one operation with the list of updates to ensure atomicity. +store_crdt(Obj, Pid) -> + Mod = antidotec_datatype:module_for_term(Obj), + Ops = Mod:to_ops(Obj), + case Ops of + undefined -> ok; + Ops -> + lists:foldl(fun(Op,Success) -> + Result = call_infinity(Pid, {req, Op, ?TIMEOUT}), + case Result of + ok -> Success; + Other -> Other + end + end, ok, Ops) + end. + +%Reads an object from the storage and returns a client-side +%representation of the CRDT. +%% @todo Handle different return messages +-spec get_crdt(term(), atom(), pid()) -> {ok, term()} | {error, term()}. +get_crdt(Key, Type, Pid) -> + Mod = antidotec_datatype:module_for_type(Type), + Op = Mod:message_for_get(Key), + case call_infinity(Pid, {req, Op, ?TIMEOUT}) of + {ok, Value} -> + {ok, Mod:new(Key,Value)}; + {error, Reason} -> {error, Reason} + end. + + + diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl new file mode 100644 index 000000000..3edf9720f --- /dev/null +++ b/src/antidotec_set.erl @@ -0,0 +1,159 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- +-module(antidotec_set). + +-include_lib("riak_pb/include/antidote_pb.hrl"). + +-behaviour(antidotec_datatype). + +-export([new/1, + new/2, + message_for_get/1, + value/1, + to_ops/1, + is_type/1, + type/0, + dirty_value/1 + ]). + +-export([add/2, + remove/2, + contains/2 + ]). + +-record(antidote_set, { + key :: term(), + set :: set(), + adds :: set(), + rems :: set() + }). + +-export_type([antidote_set/0]). +-opaque antidote_set() :: #antidote_set{}. + +-ifdef(TEST). +-compile(export_all). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + +-spec new(term()) -> antidote_set(). +new(Key) -> + #antidote_set{key=Key, set=sets:new(), adds=sets:new(), rems=sets:new()}. + +-spec new(term(), list()) -> antidote_set(). +new(Key,[]) -> + #antidote_set{key=Key, set=sets:new(), adds=sets:new(), rems=sets:new()}; + +new(Key, [_H | _] = List) -> + Set = lists:foldl(fun(E,S) -> + sets:add_element(E,S) + end,sets:new(),List), + #antidote_set{key=Key, set=Set, adds=sets:new(), rems=sets:new()}; + + +new(Key, Set) -> + #antidote_set{key=Key, set=Set, adds=sets:new(), rems=sets:new()}. + +-spec value(antidote_set()) -> set(). +value(#antidote_set{set=Set}) -> Set. + +-spec dirty_value(antidote_set()) -> set(). +dirty_value(#antidote_set{set=Set, adds=Adds}) -> + sets:union(Set,Adds). + +%% @doc Adds an element to the local set container. +-spec add(term(), antidote_set()) -> antidote_set(). +add(Elem, #antidote_set{set=Set, adds=Adds}=Fset) -> + case sets:is_element(Elem, Set) of + false -> Fset#antidote_set{adds=sets:add_element(Elem,Adds)}; + true -> Fset + end. +-spec remove(term(), antidote_set()) -> antidote_set(). +remove(Elem, #antidote_set{set=Set, adds=Adds, rems=Rems}=Fset) -> + case sets:is_element(Elem, Adds) of + true -> Fset#antidote_set{adds=sets:del_element(Elem,Adds)}; + false -> + case sets:is_element(Elem, Set) of + true -> Fset#antidote_set{rems=sets:add_element(Elem,Rems)}; + false -> Fset + end + end. + +-spec contains(term(), antidote_set()) -> boolean(). +contains(Elem, #antidote_set{set=Set, adds=Adds, rems=Rems}) -> + case sets:is_element(Elem, Adds) of + true -> true; + false -> + case sets:is_element(Elem, Set) of + true -> sets:is_element(Elem, Rems); + false -> false + end + end. + +%% @doc Determines whether the passed term is a set container. +-spec is_type(term()) -> boolean(). +is_type(T) -> + is_record(T, antidote_set). + + +%% @doc Returns the symbolic name of this container. +-spec type() -> riak_dt_orset. +type() -> riak_dt_orset. + +to_ops(#antidote_set{key=Key, adds=Adds, rems=Rems}) -> + case sets:size(Adds) =:= 0 andalso sets:size(Rems) =:= 0 of + true -> undefined; + false -> + AddsAsBin = lists:map(fun(X) -> + erlang:term_to_binary(X) + end,sets:to_list(Adds)), + RemsAsBin = lists:map(fun(X) -> + erlang:term_to_binary(X) + end,sets:to_list(Rems)), + [#fpbsetupdatereq{key=Key, adds=AddsAsBin, rems=RemsAsBin}] + end. + +message_for_get(Key) -> #fpbgetsetreq{key=Key}. + + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). +add_op_test() -> + New = antidotec_set:new(dumb_key), + EmptySet = sets:size(antidotec_set:dirty_value(New)), + OneElement = antidotec_set:add(atom1,New), + Size1Set = sets:size(antidotec_set:dirty_value(OneElement)), + [?_assert(EmptySet =:= 0), + ?_assert(Size1Set =:= 1)]. + +add_op_existing_set_test() -> + New = antidotec_set:new(dumb_key,[elem1,elem2,elem3]), + ThreeElemSet = sets:size(antidotec_set:dirty_value(New)), + AddElem = antidotec_set:add(elem4,New), + S1 = antidotec_set:remove(elem4,AddElem), + S2 = antidotec_set:remove(elem2,S1), + TwoElemSet = sets:size(antidotec_set:dirty_value(S2)), + [?_assert(ThreeElemSet =:= 3), + ?_assert(TwoElemSet =:= 2)]. +-endif. + From 8213507ffd662111f1ad9472a51a84d9cb48aac8 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 23 Jan 2015 14:14:41 +0100 Subject: [PATCH 026/426] use different rebar version --- rebar | Bin 160323 -> 148150 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/rebar b/rebar index 14e5c22455662c4eb3752852b9e436dda1d5b6e9..c66b3e6267299d0471624d1135cd403a6fd78152 100755 GIT binary patch delta 135592 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�($vOQu9^X<^t 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 YB1kKrWNg)AJQ|N4!E7jbL!n*tFCVwwJ^%m! delta 147219 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 !^{3_vccb6xX?w$ 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

r2E)vLAm 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

g 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 Date: Mon, 2 Mar 2015 12:24:41 +0100 Subject: [PATCH 027/426] atomic update and snapshot read transactions --- src/antidotec_pb_socket.erl | 154 ++++++++++++++++++++++++++++-------- 1 file changed, 121 insertions(+), 33 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 82f8dab8f..0925e1b33 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -27,8 +27,8 @@ -define(TIMEOUT, 1000). %% The TCP/IP host name or address of the Riak node --type address() :: string() | atom() | inet:ip_address(). - %% The TCP port number of the Riak node's Protocol Buffers interface +-type address() :: string() | atom() | inet:ip_address(). +%% The TCP port number of the Riak node's Protocol Buffers interface -type portnum() :: non_neg_integer(). -type msg_id() :: non_neg_integer(). -type rpb_req() :: {tunneled, msg_id(), binary()} | atom() | tuple(). @@ -57,7 +57,9 @@ -export([ store_crdt/2, - get_crdt/3 + get_crdt/3, + atomic_store_crdts/2, + snapshot_get_crdts/2 ]). %% @private @@ -111,24 +113,16 @@ handle_call(stop, _From, State) -> handle_info({_Proto, Sock, Data}, State=#state{active = (Active = #request{})}) -> <> = Data, Resp = riak_pb_codec:decode(MsgCode, MsgData), - NewState = case Resp of - %Must abstract message handling - #fpboperationresp{success = true} -> - cancel_req_timer(Active#request.tref), - _ = send_caller(ok, Active), - State#state{ active = undefined }; - #fpbgetcounterresp{value = Val} -> - cancel_req_timer(Active#request.tref), - _ = send_caller({ok,Val}, Active), - State#state{ active = undefined }; - #fpbgetsetresp{value = Val} -> - cancel_req_timer(Active#request.tref), - _ = send_caller({ok,erlang:binary_to_term(Val)}, Active), - State#state{ active = undefined }; - _ -> - lager:warning("Unexpected Message ~p",[Resp]), - State#state{ active = undefined } - end, + %%message handling + Result = case decode_response(Resp) of + error -> error; + {error,Reason} -> {error, Reason}; + ok -> ok; + Val -> {ok, Val} + end, + cancel_req_timer(Active#request.tref), + _ = send_caller(Result, Active), + NewState = State#state{ active = undefined }, ok = inet:setopts(Sock, [{active, once}]), {noreply, NewState}; @@ -191,7 +185,7 @@ disconnect(State) -> %% @private new_request(Msg, From, Timeout) -> Ref = make_ref(), - #request{ref = Ref, msg = Msg, from = From, timeout = Timeout, + #request{ref = Ref, msg = Msg, from = From, timeout = Timeout, tref = create_req_timer(Timeout, Ref)}. %% @private @@ -205,13 +199,16 @@ create_req_timer(Msecs, Ref) -> %% Send a request to the server and prepare the state for the response %% @private -send_request(Request0, State) when State#state.active =:= undefined -> +send_request(Request0, State) when State#state.active =:= undefined -> {Request, Pkt} = encode_request_message(Request0), case gen_tcp:send(State#state.sock, Pkt) of ok -> maybe_reply({noreply,State#state{active = Request}}); {error, Reason} -> lager:warning("Socket error while sending riakc request: ~p.", [Reason]), + gen_tcp:close(State#state.sock); + Other -> + lager:warning("Socket error while sending riakc request: ~p.", [Other]), gen_tcp:close(State#state.sock) end. @@ -219,15 +216,14 @@ send_request(Request0, State) when State#state.active =:= undefined -> encode_request_message(#request{msg=Msg}=Req) -> {Req, riak_pb_codec:encode(Msg)}. -%maybe_reply({reply, Reply, State = #state{active = Request}}) -> -% NewRequest = send_caller(Reply, Request), -% State#state{active = NewRequest}; +%% maybe_reply({reply, Reply, State = #state{active = Request}}) -> +%% NewRequest = send_caller(Reply, Request), +%% State#state{active = NewRequest}; maybe_reply({noreply, State = #state{}}) -> State. - -% Replies the message and clears the requester id +%% Replies the message and clears the requester id send_caller(Msg, #request{from = From}=Request) when From /= undefined -> gen_server:reply(From, Msg), Request#request{from = undefined}. @@ -240,15 +236,15 @@ cancel_req_timer(Tref) -> _ = erlang:cancel_timer(Tref), ok. -%Stores a client-side crdt to the storage by converting the object state to a -%list of oeprations that will be appended to the log. +%%Stores a client-side crdt to the storage by converting the object state to a +%%list of oeprations that will be appended to the log. %% @todo: propagate only one operation with the list of updates to ensure atomicity. store_crdt(Obj, Pid) -> Mod = antidotec_datatype:module_for_term(Obj), Ops = Mod:to_ops(Obj), case Ops of undefined -> ok; - Ops -> + Ops -> lists:foldl(fun(Op,Success) -> Result = call_infinity(Pid, {req, Op, ?TIMEOUT}), case Result of @@ -258,8 +254,8 @@ store_crdt(Obj, Pid) -> end, ok, Ops) end. -%Reads an object from the storage and returns a client-side -%representation of the CRDT. +%% Reads an object from the storage and returns a client-side +%% representation of the CRDT. %% @todo Handle different return messages -spec get_crdt(term(), atom(), pid()) -> {ok, term()} | {error, term()}. get_crdt(Key, Type, Pid) -> @@ -271,5 +267,97 @@ get_crdt(Key, Type, Pid) -> {error, Reason} -> {error, Reason} end. +%% Atomically stores multiple CRDTs converting the object state to a +%% list of operations that will be appended to the log. +-spec atomic_store_crdts([term()], pid()) -> {ok, term()} | error | {error, term()}. +atomic_store_crdts(Objects, Pid) -> + FoldFun = fun(Obj, List) -> + Mod = antidotec_datatype:module_for_term(Obj), + lists:append(List, Mod:to_ops(Obj)) + end, + Operations = lists:foldl(FoldFun, [], Objects), + TxnRequest = #fpbatomicupdatetxnreq{clock=1,ops=encode_au_txn_ops(Operations)}, + Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), + case Result of + {ok, CommitTime} -> {ok, CommitTime}; + error -> error; + {error, Reason} -> {error, Reason}; + Other -> {error, Other} + end. +%% Read multiple crdts from a consistent snapshot +-spec snapshot_get_crdts([{term(), atom()}], pid()) -> {ok, term()} | {error, term()}. +snapshot_get_crdts(Objects, Pid) -> + MapFun = fun({Key,Type}) -> + Mod = antidotec_datatype:module_for_type(Type), + Mod:message_for_get(Key) + end, + Operations = lists:map(MapFun, Objects), + TxnRequest = #fpbsnapshotreadtxnreq{clock=1,ops=encode_snapshot_read_ops(Operations)}, + Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), + case Result of + {ok, Res} -> + Zipped = lists:zip(Objects, Res), + ReadObjects = lists:map(fun({{Key,Type},Val}) -> + Mod = antidotec_datatype:module_for_type(Type), + Mod:new(Key,Val) + end, Zipped), + {ok, ReadObjects}; + error -> error; + Other -> + lager:error("Unknown message received ~p",[Other]), + {error, Other} + end. +%% Encode Atomic store crdts request into the +%% pb request message structure to be serialized +-spec encode_au_txn_ops([term()]) -> [#fpbatomicupdatetxnop{}]. +encode_au_txn_ops(Operations) -> + lists:map(fun(Op) -> encode_au_txn_op(Op) end, Operations). + +encode_au_txn_op(Op=#fpbincrementreq{}) -> + #fpbatomicupdatetxnop{counterinc=Op}; +encode_au_txn_op(Op=#fpbdecrementreq{}) -> + #fpbatomicupdatetxnop{counterdec=Op}; +encode_au_txn_op(Op=#fpbsetupdatereq{}) -> + #fpbatomicupdatetxnop{setupdate=Op}. + + +%% Encode Snapshot read request into the +%% pb request message record to be serialized +-spec encode_snapshot_read_ops([term()]) -> [#fpbsnapshotreadtxnop{}]. +encode_snapshot_read_ops(Operations) -> + lists:map(fun(Op) -> encode_snapshot_read_op(Op) end, Operations). + +encode_snapshot_read_op(Op=#fpbgetcounterreq{}) -> + #fpbsnapshotreadtxnop{counter=Op}; +encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> + #fpbsnapshotreadtxnop{set=Op}. + +%% Decode response of pb request +decode_response(#fpboperationresp{success = true}) -> ok; +decode_response(#fpbgetcounterresp{value = Val}) -> + Val; +decode_response(#fpbgetsetresp{value = Val}) -> + erlang:binary_to_term(Val); +decode_response(#fpbatomicupdatetxnresp{success = Success, committime = CommitTime}) -> + case Success of + true -> + CommitTime; + false -> + error + end; +decode_response(#fpbsnapshotreadtxnresp{success = Success, results=Result}) -> + case Success of + true -> + lists:map(fun(X) -> decode_response(X) end, Result); + _ -> + {error, request_failed} + end; +decode_response(#fpbsnapshotreadtxnrespvalue{counter=Counter, set=undefined}) -> + decode_response(Counter); +decode_response(#fpbsnapshotreadtxnrespvalue{counter=undefined, set=Set}) -> + decode_response(Set); +decode_response(Resp) -> + lager:error("Unexpected Message ~p",[Resp]), + error. From 2de423815e184b2e1dfca4cb9d8c3a4f66ca4685 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Mon, 2 Mar 2015 15:42:13 +0100 Subject: [PATCH 028/426] include clocks in pb transactions --- src/antidotec_pb_socket.erl | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 0925e1b33..0e5a526f9 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -269,14 +269,21 @@ get_crdt(Key, Type, Pid) -> %% Atomically stores multiple CRDTs converting the object state to a %% list of operations that will be appended to the log. --spec atomic_store_crdts([term()], pid()) -> {ok, term()} | error | {error, term()}. -atomic_store_crdts(Objects, Pid) -> +atomic_store_crdts(Object,Pid) -> + atomic_store_crdts(Object, ignore, Pid). +-spec atomic_store_crdts([term()], ignore|term(), pid()) -> {ok, term()} | error | {error, term()}. +atomic_store_crdts(Objects, Clock, Pid) -> FoldFun = fun(Obj, List) -> Mod = antidotec_datatype:module_for_term(Obj), lists:append(List, Mod:to_ops(Obj)) end, Operations = lists:foldl(FoldFun, [], Objects), - TxnRequest = #fpbatomicupdatetxnreq{clock=1,ops=encode_au_txn_ops(Operations)}, + TxnRequest = case Clock of + ignore -> + #fpbatomicupdatetxnreq{ops=encode_au_txn_ops(Operations)}; + _ -> + #fpbatomicupdatetxnreq{clock=Clock,ops=encode_au_txn_ops(Operations)} + end, Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), case Result of {ok, CommitTime} -> {ok, CommitTime}; @@ -286,23 +293,31 @@ atomic_store_crdts(Objects, Pid) -> end. %% Read multiple crdts from a consistent snapshot +snapshot_get_crdts(Objects,Pid) -> + snapshot_get_crdts(Objects, ignore, Pid). + -spec snapshot_get_crdts([{term(), atom()}], pid()) -> {ok, term()} | {error, term()}. -snapshot_get_crdts(Objects, Pid) -> +snapshot_get_crdts(Objects, Clock, Pid) -> MapFun = fun({Key,Type}) -> Mod = antidotec_datatype:module_for_type(Type), Mod:message_for_get(Key) end, Operations = lists:map(MapFun, Objects), - TxnRequest = #fpbsnapshotreadtxnreq{clock=1,ops=encode_snapshot_read_ops(Operations)}, + TxnRequest = case Clock of + ignore -> + #fpbsnapshotreadtxnreq{ops=encode_snapshot_read_ops(Operations)}; + _ -> + #fpbsnapshotreadtxnreq{clock=Clock,ops=encode_snapshot_read_ops(Operations)} + end, Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), case Result of - {ok, Res} -> + {ok, {NewClock, Res}} -> Zipped = lists:zip(Objects, Res), ReadObjects = lists:map(fun({{Key,Type},Val}) -> Mod = antidotec_datatype:module_for_type(Type), Mod:new(Key,Val) end, Zipped), - {ok, ReadObjects}; + {ok, NewClock, ReadObjects}; error -> error; Other -> lager:error("Unknown message received ~p",[Other]), @@ -340,17 +355,18 @@ decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> erlang:binary_to_term(Val); -decode_response(#fpbatomicupdatetxnresp{success = Success, committime = CommitTime}) -> +decode_response(#fpbatomicupdatetxnresp{success = Success, clock = CommitTime}) -> case Success of true -> CommitTime; false -> error end; -decode_response(#fpbsnapshotreadtxnresp{success = Success, results=Result}) -> +decode_response(#fpbsnapshotreadtxnresp{success = Success, clock=Clock, results=Result}) -> case Success of true -> - lists:map(fun(X) -> decode_response(X) end, Result); + Res = lists:map(fun(X) -> decode_response(X) end, Result), + {Clock, Res}; _ -> {error, request_failed} end; From 3ea8fc29cad635b63eb5ea3d1bdf54fd73721ba3 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 6 Mar 2015 14:35:12 +0100 Subject: [PATCH 029/426] fix set contain --- src/antidotec_set.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index 3edf9720f..51ed6e161 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -103,7 +103,7 @@ contains(Elem, #antidote_set{set=Set, adds=Adds, rems=Rems}) -> true -> true; false -> case sets:is_element(Elem, Set) of - true -> sets:is_element(Elem, Rems); + true -> not sets:is_element(Elem, Rems); false -> false end end. From 69de0c55e1abb1453209a06f400ad89942239c0c Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Mon, 16 Mar 2015 12:20:29 +0100 Subject: [PATCH 030/426] fix makefile --- Makefile | 145 +++++++------------------------------------------------ 1 file changed, 17 insertions(+), 128 deletions(-) diff --git a/Makefile b/Makefile index de08aceba..142ec4d57 100644 --- a/Makefile +++ b/Makefile @@ -1,137 +1,26 @@ -# Copyright 2012 Erlware, LLC. All Rights Reserved. -# -# This file is provided to you under the Apache License, -# Version 2.0 (the "License"); you may not use this file -# except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -ERLFLAGS= -pa $(CURDIR)/.eunit -pa $(CURDIR)/ebin -pa $(CURDIR)/deps/*/ebin - -DEPS_PLT=$(CURDIR)/.deps_plt -DEPS=erts kernel stdlib - -# ============================================================================= -# Verify that the programs we need to run are installed on this system -# ============================================================================= -ERL = $(shell which erl) - -ifeq ($(ERL),) -$(error "Erlang not available on this system") -endif - -# REBAR=$(shell which rebar) -# ifeq ($(REBAR),) -# $(error "Rebar not available on this system") -# endif +.PHONY: rel deps test -REBAR=./rebar - - -.PHONY: all compile doc clean test dialyzer typer shell distclean pdf \ - update-deps clean-common-test-data rebuild - -all: deps compile test - -# ============================================================================= -# Rules to build the system -# ============================================================================= - -deps: - $(REBAR) get-deps - $(REBAR) compile - -update-deps: - $(REBAR) update-deps - $(REBAR) compile - -compile: - $(REBAR) skip_deps=true compile - -doc: - $(REBAR) skip_deps=true doc - -eunit: compile clean-common-test-data - $(REBAR) skip_deps=true eunit - -$(TEST_DEPS): - @echo Running EUnit - -test: compile eunit - -PLT ?= $(HOME)/.combo_dialyzer_plt -LOCAL_PLT = .local_dialyzer_plt -DIALYZER_FLAGS ?= -Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspecs +all: deps compile -${PLT}: compile - @if [ -f $(PLT) ]; then \ - dialyzer --check_plt --plt $(PLT) && \ - dialyzer --add_to_plt --plt $(PLT) --output_plt $(PLT) ; test $$? -ne 1; \ - else \ - dialyzer --build_plt --output_plt $(PLT) ; test $$? -ne 1; \ - fi +compile: deps + @./rebar compile -${LOCAL_PLT}: compile - @if [ -d deps ]; then \ - if [ -f $(LOCAL_PLT) ]; then \ - dialyzer --check_plt --plt $(LOCAL_PLT) deps/*/ebin && \ - dialyzer --add_to_plt --plt $(LOCAL_PLT) --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ - else \ - dialyzer --build_plt --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ - fi \ - fi +app: + @./rebar compile skip_deps=true -dialyzer: ${PLT} ${LOCAL_PLT} - @echo "==> $(shell basename $(shell pwd)) (dialyzer)" - @if [ -f $(LOCAL_PLT) ]; then \ - PLTS="$(PLT) $(LOCAL_PLT)"; \ - else \ - PLTS=$(PLT); \ - fi; \ - if [ -f dialyzer.ignore-warnings ]; then \ - if [ $$(grep -cvE '[^[:space:]]' dialyzer.ignore-warnings) -ne 0 ]; then \ - echo "ERROR: dialyzer.ignore-warnings contains a blank/empty line, this will match all messages!"; \ - exit 1; \ - fi; \ - dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin > dialyzer_warnings ; \ - egrep -v "^[[:space:]]*(done|Checking|Proceeding|Compiling)" dialyzer_warnings | grep -F -f dialyzer.ignore-warnings -v > dialyzer_unhandled_warnings ; \ - cat dialyzer_unhandled_warnings ; \ - [ $$(cat dialyzer_unhandled_warnings | wc -l) -eq 0 ] ; \ - else \ - dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin; \ - fi +deps: + @./rebar get-deps -typer: - typer --plt $(DEPS_PLT) -r ./src - -shell: deps compile -# You often want *rebuilt* rebar tests to be available to the -# shell you have to call eunit (to get the tests -# rebuilt). However, eunit runs the tests, which probably -# fails (thats probably why You want them in the shell). This -# runs eunit but tells make to ignore the result. - - @$(REBAR) skip_deps=true eunit - @$(ERL) $(ERLFLAGS) - clean: - - rm -rf $(CURDIR)/test/*.beam - - rm -rf $(CURDIR)/logs - - rm -rf $(CURDIR)/ebin - $(REBAR) skip_deps=true clean - + @./rebar clean + distclean: clean - - rm -rf $(DEPS_PLT) - - rm -rvf $(CURDIR)/deps - -rebuild: distclean deps compile escript dialyzer test + @./rebar delete-deps + +DIALYZER_APPS = kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \ + xmerl webtool eunit syntax_tools compiler mnesia public_key snmp +include tools.mk +typer: + typer --annotate -I ../ --plt $(PLT) -r src From f03ae57225f732135737e1ad2da6efe09ec57f47 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Sun, 3 May 2015 19:05:43 +0100 Subject: [PATCH 031/426] Add error handling --- include/antidote_pb.hrl | 59 +++++++++++++++++++++++++++++++++++++ src/antidotec_counter.erl | 2 +- src/antidotec_pb_socket.erl | 3 +- src/antidotec_set.erl | 2 +- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 include/antidote_pb.hrl diff --git a/include/antidote_pb.hrl b/include/antidote_pb.hrl new file mode 100644 index 000000000..11dade41f --- /dev/null +++ b/include/antidote_pb.hrl @@ -0,0 +1,59 @@ +-ifndef(FPBINCREMENTREQ_PB_H). +-define(FPBINCREMENTREQ_PB_H, true). +-record(fpbincrementreq, { + key = erlang:error({required, key}), + amount = erlang:error({required, amount}) +}). +-endif. + +-ifndef(FPBDECREMENTREQ_PB_H). +-define(FPBDECREMENTREQ_PB_H, true). +-record(fpbdecrementreq, { + key = erlang:error({required, key}), + amount = erlang:error({required, amount}) +}). +-endif. + +-ifndef(FPBGETCOUNTERREQ_PB_H). +-define(FPBGETCOUNTERREQ_PB_H, true). +-record(fpbgetcounterreq, { + key = erlang:error({required, key}) +}). +-endif. + +-ifndef(FPBGETCOUNTERRESP_PB_H). +-define(FPBGETCOUNTERRESP_PB_H, true). +-record(fpbgetcounterresp, { + value = erlang:error({required, value}) +}). +-endif. + +-ifndef(FPBOPERATIONRESP_PB_H). +-define(FPBOPERATIONRESP_PB_H, true). +-record(fpboperationresp, { + success = erlang:error({required, success}) +}). +-endif. + +-ifndef(FPBSETUPDATEREQ_PB_H). +-define(FPBSETUPDATEREQ_PB_H, true). +-record(fpbsetupdatereq, { + key = erlang:error({required, key}), + adds = [], + rems = [] +}). +-endif. + +-ifndef(FPBGETSETREQ_PB_H). +-define(FPBGETSETREQ_PB_H, true). +-record(fpbgetsetreq, { + key = erlang:error({required, key}) +}). +-endif. + +-ifndef(FPBGETSETRESP_PB_H). +-define(FPBGETSETRESP_PB_H, true). +-record(fpbgetsetresp, { + value = erlang:error({required, value}) +}). +-endif. diff --git a/src/antidotec_counter.erl b/src/antidotec_counter.erl index ba70a73f7..5e3b0e4dd 100644 --- a/src/antidotec_counter.erl +++ b/src/antidotec_counter.erl @@ -19,7 +19,7 @@ %% ------------------------------------------------------------------- -module(antidotec_counter). --include_lib("riak_pb/include/antidote_pb.hrl"). +-include_lib("include/antidote_pb.hrl"). -behaviour(antidotec_datatype). diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 0e5a526f9..7db56e4c2 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -19,7 +19,7 @@ %% ------------------------------------------------------------------- -module(antidotec_pb_socket). --include_lib("riak_pb/include/antidote_pb.hrl"). +-include_lib("include/antidote_pb.hrl"). -behaviour(gen_server). @@ -351,6 +351,7 @@ encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> %% Decode response of pb request decode_response(#fpboperationresp{success = true}) -> ok; +decode_response(#fpboperationresp{success = false}) -> error; decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index 51ed6e161..e46e6d3a4 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -19,7 +19,7 @@ %% ------------------------------------------------------------------- -module(antidotec_set). --include_lib("riak_pb/include/antidote_pb.hrl"). +-include_lib("include/antidote_pb.hrl"). -behaviour(antidotec_datatype). From 19aff543701df675ec1993ad9d4567729b077d90 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 4 May 2015 20:20:29 +0100 Subject: [PATCH 032/426] Add error info --- src/antidotec_pb_socket.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 7db56e4c2..6c2dd2d7d 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -351,7 +351,7 @@ encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> %% Decode response of pb request decode_response(#fpboperationresp{success = true}) -> ok; -decode_response(#fpboperationresp{success = false}) -> error; +decode_response(#fpboperationresp{success = false}) -> {error, failed}; decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> From 9681bef082acf8a962722f69dc279b0d1ef38322 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 4 May 2015 22:26:30 +0100 Subject: [PATCH 033/426] Add antidote_pb --- include/antidote_pb.hrl | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/include/antidote_pb.hrl b/include/antidote_pb.hrl index 11dade41f..ea97a2f3a 100644 --- a/include/antidote_pb.hrl +++ b/include/antidote_pb.hrl @@ -57,3 +57,63 @@ value = erlang:error({required, value}) }). -endif. + +-ifndef(FPBATOMICUPDATETXNOP_PB_H). +-define(FPBATOMICUPDATETXNOP_PB_H, true). +-record(fpbatomicupdatetxnop, { + counterinc, + counterdec, + setupdate +}). +-endif. + +-ifndef(FPBATOMICUPDATETXNREQ_PB_H). +-define(FPBATOMICUPDATETXNREQ_PB_H, true). +-record(fpbatomicupdatetxnreq, { + clock, + ops = [] +}). +-endif. + +-ifndef(FPBATOMICUPDATETXNRESP_PB_H). +-define(FPBATOMICUPDATETXNRESP_PB_H, true). +-record(fpbatomicupdatetxnresp, { + success = erlang:error({required, success}), + clock +}). +-endif. + +-ifndef(FPBSNAPSHOTREADTXNOP_PB_H). +-define(FPBSNAPSHOTREADTXNOP_PB_H, true). +-record(fpbsnapshotreadtxnop, { + counter, + set +}). +-endif. + +-ifndef(FPBSNAPSHOTREADTXNREQ_PB_H). +-define(FPBSNAPSHOTREADTXNREQ_PB_H, true). +-record(fpbsnapshotreadtxnreq, { + clock, + ops = [] +}). +-endif. + +-ifndef(FPBSNAPSHOTREADTXNRESPVALUE_PB_H). +-define(FPBSNAPSHOTREADTXNRESPVALUE_PB_H, true). +-record(fpbsnapshotreadtxnrespvalue, { + key = erlang:error({required, key}), + counter, + set +}). +-endif. + +-ifndef(FPBSNAPSHOTREADTXNRESP_PB_H). +-define(FPBSNAPSHOTREADTXNRESP_PB_H, true). +-record(fpbsnapshotreadtxnresp, { + success = erlang:error({required, success}), + clock, + results = [] +}). +-endif. + From 5916e41128a7a777591d2b660d3468e934b9f5a1 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 4 May 2015 22:54:21 +0100 Subject: [PATCH 034/426] Fix error handling --- src/antidotec_pb_socket.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 6c2dd2d7d..19f6919b1 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -350,8 +350,13 @@ encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> #fpbsnapshotreadtxnop{set=Op}. %% Decode response of pb request -decode_response(#fpboperationresp{success = true}) -> ok; -decode_response(#fpboperationresp{success = false}) -> {error, failed}; +decode_response(#fpboperationresp{success = Success}) -> + case Success of + true -> + ok; + false -> + {error, failed} + end; decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> From 5329c858f63a9b35f054df1773d1880bebf09b8b Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 4 May 2015 23:42:07 +0100 Subject: [PATCH 035/426] Test if works] --- src/antidotec_pb_socket.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 19f6919b1..ec1d6672e 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -381,5 +381,5 @@ decode_response(#fpbsnapshotreadtxnrespvalue{counter=Counter, set=undefined}) -> decode_response(#fpbsnapshotreadtxnrespvalue{counter=undefined, set=Set}) -> decode_response(Set); decode_response(Resp) -> - lager:error("Unexpected Message ~p",[Resp]), + lager:error("Unexpected Message WRONG ~p",[Resp]), error. From e1fa4d3e3104b6f6eaa1568441ffa3d5b6ffa455 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Mon, 4 May 2015 23:51:14 +0100 Subject: [PATCH 036/426] Stable --- src/antidotec_pb_socket.erl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index ec1d6672e..bf4905e65 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -350,13 +350,8 @@ encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> #fpbsnapshotreadtxnop{set=Op}. %% Decode response of pb request -decode_response(#fpboperationresp{success = Success}) -> - case Success of - true -> - ok; - false -> - {error, failed} - end; +decode_response(#fpboperationresp{success = true}) -> ok; +decode_response(#fpboperationresp{success = false}) -> {error, failed}; decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> From 6ad03112d010f14f14c0d3cdd70950304ec58a8d Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 5 May 2015 10:51:03 +0100 Subject: [PATCH 037/426] Remove duplicate error message --- src/antidotec_pb_socket.erl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index bf4905e65..35f59a910 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -320,7 +320,6 @@ snapshot_get_crdts(Objects, Clock, Pid) -> {ok, NewClock, ReadObjects}; error -> error; Other -> - lager:error("Unknown message received ~p",[Other]), {error, Other} end. From bf005060f24acc6c0f0cc9983042e09c07a4ce2f Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 5 May 2015 10:57:51 +0100 Subject: [PATCH 038/426] Handle no snapshot --- src/antidotec_pb_socket.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 35f59a910..da9751cc4 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -350,7 +350,7 @@ encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> %% Decode response of pb request decode_response(#fpboperationresp{success = true}) -> ok; -decode_response(#fpboperationresp{success = false}) -> {error, failed}; +decode_response(#fpboperationresp{success = false}) -> {error, no_snapshot}; decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> From cfe12159083e19f6db470cd82445297ef9cce9ad Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 5 May 2015 11:07:32 +0100 Subject: [PATCH 039/426] Finally correct handle error --- src/antidotec_pb_socket.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index da9751cc4..0e4172ce7 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -319,6 +319,7 @@ snapshot_get_crdts(Objects, Clock, Pid) -> end, Zipped), {ok, NewClock, ReadObjects}; error -> error; + {error, Reason} -> {error, Reason}; Other -> {error, Other} end. @@ -375,5 +376,5 @@ decode_response(#fpbsnapshotreadtxnrespvalue{counter=Counter, set=undefined}) -> decode_response(#fpbsnapshotreadtxnrespvalue{counter=undefined, set=Set}) -> decode_response(Set); decode_response(Resp) -> - lager:error("Unexpected Message WRONG ~p",[Resp]), + lager:error("Unexpected Message ~p",[Resp]), error. From e935e4ebd9c1a87772715145f4b99104640c7179 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 5 May 2015 14:44:57 +0100 Subject: [PATCH 040/426] Change key from byte to integer --- src/antidotec_datatype.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_datatype.erl b/src/antidotec_datatype.erl index c58da3ba6..01102f6f4 100644 --- a/src/antidotec_datatype.erl +++ b/src/antidotec_datatype.erl @@ -41,7 +41,7 @@ %% @doc Constructs a new container for the type with the specified %% value and key. This should only be used internally by the client code. --callback new(Key::binary(), Value::term()) -> datatype(). +-callback new(Key::integer(), Value::term()) -> datatype(). %% @doc Returns the original, unmodified value of the object. This does %% not include the execution of any locally-queued operations. From 6a8b614a1d7cc1e732368adabdbe615190c6fa9e Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 5 May 2015 14:46:07 +0100 Subject: [PATCH 041/426] Revert --- src/antidotec_datatype.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_datatype.erl b/src/antidotec_datatype.erl index 01102f6f4..941ecd29c 100644 --- a/src/antidotec_datatype.erl +++ b/src/antidotec_datatype.erl @@ -41,7 +41,7 @@ %% @doc Constructs a new container for the type with the specified %% value and key. This should only be used internally by the client code. --callback new(Key::integer(), Value::term()) -> datatype(). +-callback new(Key::byte(), Value::term()) -> datatype(). %% @doc Returns the original, unmodified value of the object. This does %% not include the execution of any locally-queued operations. From f369efb616fcd080b731b69e8892efe5864e43bb Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 19 May 2015 22:39:42 +0100 Subject: [PATCH 042/426] Unspecify error reason; it is output in antidote_pb --- src/antidotec_pb_socket.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 0e4172ce7..7228685d4 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -351,7 +351,7 @@ encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> %% Decode response of pb request decode_response(#fpboperationresp{success = true}) -> ok; -decode_response(#fpboperationresp{success = false}) -> {error, no_snapshot}; +decode_response(#fpboperationresp{success = false}) -> {error, failed}; decode_response(#fpbgetcounterresp{value = Val}) -> Val; decode_response(#fpbgetsetresp{value = Val}) -> From 1ec8d4c10d09a329ada8fc92b82631bb91df9d2c Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 22 May 2015 12:05:54 +0200 Subject: [PATCH 043/426] export interfaces using clock --- src/antidotec_pb_socket.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 7228685d4..9ba533d1a 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -59,7 +59,9 @@ store_crdt/2, get_crdt/3, atomic_store_crdts/2, - snapshot_get_crdts/2 + atomic_store_crdts/3, + snapshot_get_crdts/2, + snapshot_get_crdts/3 ]). %% @private From 250af41b3edf3024bfbd26318cc08be364a913ac Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 22 May 2015 12:06:40 +0200 Subject: [PATCH 044/426] remove file which doesnot belong here --- include/antidote_pb.hrl | 119 ---------------------------------------- 1 file changed, 119 deletions(-) delete mode 100644 include/antidote_pb.hrl diff --git a/include/antidote_pb.hrl b/include/antidote_pb.hrl deleted file mode 100644 index ea97a2f3a..000000000 --- a/include/antidote_pb.hrl +++ /dev/null @@ -1,119 +0,0 @@ --ifndef(FPBINCREMENTREQ_PB_H). --define(FPBINCREMENTREQ_PB_H, true). --record(fpbincrementreq, { - key = erlang:error({required, key}), - amount = erlang:error({required, amount}) -}). --endif. - --ifndef(FPBDECREMENTREQ_PB_H). --define(FPBDECREMENTREQ_PB_H, true). --record(fpbdecrementreq, { - key = erlang:error({required, key}), - amount = erlang:error({required, amount}) -}). --endif. - --ifndef(FPBGETCOUNTERREQ_PB_H). --define(FPBGETCOUNTERREQ_PB_H, true). --record(fpbgetcounterreq, { - key = erlang:error({required, key}) -}). --endif. - --ifndef(FPBGETCOUNTERRESP_PB_H). --define(FPBGETCOUNTERRESP_PB_H, true). --record(fpbgetcounterresp, { - value = erlang:error({required, value}) -}). --endif. - --ifndef(FPBOPERATIONRESP_PB_H). --define(FPBOPERATIONRESP_PB_H, true). --record(fpboperationresp, { - success = erlang:error({required, success}) -}). --endif. - --ifndef(FPBSETUPDATEREQ_PB_H). --define(FPBSETUPDATEREQ_PB_H, true). --record(fpbsetupdatereq, { - key = erlang:error({required, key}), - adds = [], - rems = [] -}). --endif. - --ifndef(FPBGETSETREQ_PB_H). --define(FPBGETSETREQ_PB_H, true). --record(fpbgetsetreq, { - key = erlang:error({required, key}) -}). --endif. - --ifndef(FPBGETSETRESP_PB_H). --define(FPBGETSETRESP_PB_H, true). --record(fpbgetsetresp, { - value = erlang:error({required, value}) -}). --endif. - --ifndef(FPBATOMICUPDATETXNOP_PB_H). --define(FPBATOMICUPDATETXNOP_PB_H, true). --record(fpbatomicupdatetxnop, { - counterinc, - counterdec, - setupdate -}). --endif. - --ifndef(FPBATOMICUPDATETXNREQ_PB_H). --define(FPBATOMICUPDATETXNREQ_PB_H, true). --record(fpbatomicupdatetxnreq, { - clock, - ops = [] -}). --endif. - --ifndef(FPBATOMICUPDATETXNRESP_PB_H). --define(FPBATOMICUPDATETXNRESP_PB_H, true). --record(fpbatomicupdatetxnresp, { - success = erlang:error({required, success}), - clock -}). --endif. - --ifndef(FPBSNAPSHOTREADTXNOP_PB_H). --define(FPBSNAPSHOTREADTXNOP_PB_H, true). --record(fpbsnapshotreadtxnop, { - counter, - set -}). --endif. - --ifndef(FPBSNAPSHOTREADTXNREQ_PB_H). --define(FPBSNAPSHOTREADTXNREQ_PB_H, true). --record(fpbsnapshotreadtxnreq, { - clock, - ops = [] -}). --endif. - --ifndef(FPBSNAPSHOTREADTXNRESPVALUE_PB_H). --define(FPBSNAPSHOTREADTXNRESPVALUE_PB_H, true). --record(fpbsnapshotreadtxnrespvalue, { - key = erlang:error({required, key}), - counter, - set -}). --endif. - --ifndef(FPBSNAPSHOTREADTXNRESP_PB_H). --define(FPBSNAPSHOTREADTXNRESP_PB_H, true). --record(fpbsnapshotreadtxnresp, { - success = erlang:error({required, success}), - clock, - results = [] -}). --endif. - From 2d505705108aa7e5e94c68005f8f88b6e7de5f73 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 22 May 2015 13:42:42 +0200 Subject: [PATCH 045/426] use riak_pb include --- src/antidotec_counter.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_counter.erl b/src/antidotec_counter.erl index 5e3b0e4dd..ba70a73f7 100644 --- a/src/antidotec_counter.erl +++ b/src/antidotec_counter.erl @@ -19,7 +19,7 @@ %% ------------------------------------------------------------------- -module(antidotec_counter). --include_lib("include/antidote_pb.hrl"). +-include_lib("riak_pb/include/antidote_pb.hrl"). -behaviour(antidotec_datatype). From 7fad3a55865fcdba43775e347d3070ed9713a5a5 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 22 May 2015 13:44:53 +0200 Subject: [PATCH 046/426] use riak_pb include --- src/antidotec_pb_socket.erl | 2 +- src/antidotec_set.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 9ba533d1a..55cd1d2bd 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -19,7 +19,7 @@ %% ------------------------------------------------------------------- -module(antidotec_pb_socket). --include_lib("include/antidote_pb.hrl"). +-include_lib("riak_pb/include/antidote_pb.hrl"). -behaviour(gen_server). diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index e46e6d3a4..51ed6e161 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -19,7 +19,7 @@ %% ------------------------------------------------------------------- -module(antidotec_set). --include_lib("include/antidote_pb.hrl"). +-include_lib("riak_pb/include/antidote_pb.hrl"). -behaviour(antidotec_datatype). From e1803773a3dc9816c308948cc7c81403fa18d21a Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 22 May 2015 13:52:49 +0200 Subject: [PATCH 047/426] reset clock if not specified --- src/antidotec_pb_socket.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 55cd1d2bd..db7eacd44 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -282,7 +282,7 @@ atomic_store_crdts(Objects, Clock, Pid) -> Operations = lists:foldl(FoldFun, [], Objects), TxnRequest = case Clock of ignore -> - #fpbatomicupdatetxnreq{ops=encode_au_txn_ops(Operations)}; + #fpbatomicupdatetxnreq{clock=ignore,ops=encode_au_txn_ops(Operations)}; _ -> #fpbatomicupdatetxnreq{clock=Clock,ops=encode_au_txn_ops(Operations)} end, @@ -307,9 +307,9 @@ snapshot_get_crdts(Objects, Clock, Pid) -> Operations = lists:map(MapFun, Objects), TxnRequest = case Clock of ignore -> - #fpbsnapshotreadtxnreq{ops=encode_snapshot_read_ops(Operations)}; + #fpbsnapshotreadtxnreq{clock=ignore, ops=encode_snapshot_read_ops(Operations)}; _ -> - #fpbsnapshotreadtxnreq{clock=Clock,ops=encode_snapshot_read_ops(Operations)} + #fpbsnapshotreadtxnreq{clock=Clock, ops=encode_snapshot_read_ops(Operations)} end, Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), case Result of From c20802282080e8189d3784decb6fe0940e7f4cee Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Fri, 22 May 2015 13:59:27 +0200 Subject: [PATCH 048/426] fix encoding --- src/antidotec_pb_socket.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index db7eacd44..a8c8a6250 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -282,7 +282,7 @@ atomic_store_crdts(Objects, Clock, Pid) -> Operations = lists:foldl(FoldFun, [], Objects), TxnRequest = case Clock of ignore -> - #fpbatomicupdatetxnreq{clock=ignore,ops=encode_au_txn_ops(Operations)}; + #fpbatomicupdatetxnreq{clock=term_to_binary(ignore),ops=encode_au_txn_ops(Operations)}; _ -> #fpbatomicupdatetxnreq{clock=Clock,ops=encode_au_txn_ops(Operations)} end, @@ -307,7 +307,7 @@ snapshot_get_crdts(Objects, Clock, Pid) -> Operations = lists:map(MapFun, Objects), TxnRequest = case Clock of ignore -> - #fpbsnapshotreadtxnreq{clock=ignore, ops=encode_snapshot_read_ops(Operations)}; + #fpbsnapshotreadtxnreq{clock=term_to_binary(ignore), ops=encode_snapshot_read_ops(Operations)}; _ -> #fpbsnapshotreadtxnreq{clock=Clock, ops=encode_snapshot_read_ops(Operations)} end, From 06b93e6f3fc93f9a8c521f6d637eb581cd884e85 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 26 May 2015 14:43:01 +0100 Subject: [PATCH 049/426] Increasing timeout --- src/antidotec_pb_socket.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index a8c8a6250..d0e02e83f 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -24,7 +24,7 @@ -behaviour(gen_server). -define(FIRST_RECONNECT_INTERVAL, 100). --define(TIMEOUT, 1000). +-define(TIMEOUT, 5000). %% The TCP/IP host name or address of the Riak node -type address() :: string() | atom() | inet:ip_address(). From e18b3bdfdd695303658356aee325573ba54423e7 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 27 Aug 2015 13:56:15 +0200 Subject: [PATCH 050/426] added basic support for interactive transactions --- src/antidotec_pb.erl | 102 ++++++++++++++++++++++++++++++++++++ src/antidotec_pb_socket.erl | 48 +++-------------- 2 files changed, 109 insertions(+), 41 deletions(-) create mode 100644 src/antidotec_pb.erl diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl new file mode 100644 index 000000000..154e66e87 --- /dev/null +++ b/src/antidotec_pb.erl @@ -0,0 +1,102 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- +-module(antidotec_pb). + +-include_lib("riak_pb/include/antidote_pb.hrl"). + + +-export([start_transaction/3, + abort_transaction/2, + commit_transaction/2, + update_objects/3, + read_objects/3]). + +-define(TIMEOUT, 10000). + +-spec start_transaction(Pid::term(), TimeStamp::term(), TxnProperties::term()) -> {ok, term()} | {error, term()}. +start_transaction(Pid, TimeStamp, TxnProperties) -> + EncMsg = antidote_pb_codec:encode(start_transaction, {TimeStamp, TxnProperties}), + Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {start_transaction, TxId} -> + {ok, TxId}; + {error, Reason} -> + {error, Reason}; + Other -> + {error, Other} + end + end. + +-spec abort_transaction(Pid::term(), TxId::term()) -> ok. +abort_transaction(Pid, TxId) -> + EncMsg = antidote_pb_codec:encode(abort_transaction, TxId), + Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {opresponse, ok} -> ok; + {error, Reason} -> {error, Reason}; + Other -> {error, Other} + end + end. + +-spec commit_transaction(Pid::term(), TxId::term()) -> {ok, term()} | {error, term()}. +commit_transaction(Pid, TxId) -> + EncMsg = antidote_pb_codec:encode(commit_transaction, TxId), + Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {commit_transaction, CommitTimeStamp} -> {ok, CommitTimeStamp}; + {error, Reason} -> {error, Reason}; + Other -> {error, Other} + end + end. + +update_objects(Pid, Updates, TxId) -> + EncMsg = antidote_pb_codec: encode(update_objects, {Updates, TxId}), + Result = antidotec_pb_socket: call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec: decode_response(Result) of + {opresponse, ok} -> ok; + {error, Reason} -> {error, Reason}; + Other -> {error, Other} + end + end. + +read_objects(Pid, Objects, TxId) -> + EncMsg = antidote_pb_codec:encode(read_objects, {Objects, TxId}), + Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {read_objects, Values} -> {ok, Values}; + {error, Reason} -> {error, Reason}; + Other -> {error, Other} + end + end. diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index a8c8a6250..dca34b662 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -61,7 +61,8 @@ atomic_store_crdts/2, atomic_store_crdts/3, snapshot_get_crdts/2, - snapshot_get_crdts/3 + snapshot_get_crdts/3, + call_infinity/2 ]). %% @private @@ -114,17 +115,11 @@ handle_call(stop, _From, State) -> %% @todo handle timeout handle_info({_Proto, Sock, Data}, State=#state{active = (Active = #request{})}) -> <> = Data, - Resp = riak_pb_codec:decode(MsgCode, MsgData), - %%message handling - Result = case decode_response(Resp) of - error -> error; - {error,Reason} -> {error, Reason}; - ok -> ok; - Val -> {ok, Val} - end, + Response = riak_pb_codec:decode(MsgCode, MsgData), + lager:info("Response ~p", [Response]), cancel_req_timer(Active#request.tref), - _ = send_caller(Result, Active), - NewState = State#state{ active = undefined }, + _ = send_caller(Response, Active), + NewState = State#state{active = undefined}, ok = inet:setopts(Sock, [{active, once}]), {noreply, NewState}; @@ -203,6 +198,7 @@ create_req_timer(Msecs, Ref) -> %% @private send_request(Request0, State) when State#state.active =:= undefined -> {Request, Pkt} = encode_request_message(Request0), + lager:info("Sending message"), case gen_tcp:send(State#state.sock, Pkt) of ok -> maybe_reply({noreply,State#state{active = Request}}); @@ -350,33 +346,3 @@ encode_snapshot_read_op(Op=#fpbgetcounterreq{}) -> #fpbsnapshotreadtxnop{counter=Op}; encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> #fpbsnapshotreadtxnop{set=Op}. - -%% Decode response of pb request -decode_response(#fpboperationresp{success = true}) -> ok; -decode_response(#fpboperationresp{success = false}) -> {error, failed}; -decode_response(#fpbgetcounterresp{value = Val}) -> - Val; -decode_response(#fpbgetsetresp{value = Val}) -> - erlang:binary_to_term(Val); -decode_response(#fpbatomicupdatetxnresp{success = Success, clock = CommitTime}) -> - case Success of - true -> - CommitTime; - false -> - error - end; -decode_response(#fpbsnapshotreadtxnresp{success = Success, clock=Clock, results=Result}) -> - case Success of - true -> - Res = lists:map(fun(X) -> decode_response(X) end, Result), - {Clock, Res}; - _ -> - {error, request_failed} - end; -decode_response(#fpbsnapshotreadtxnrespvalue{counter=Counter, set=undefined}) -> - decode_response(Counter); -decode_response(#fpbsnapshotreadtxnrespvalue{counter=undefined, set=Set}) -> - decode_response(Set); -decode_response(Resp) -> - lager:error("Unexpected Message ~p",[Resp]), - error. From 2b4c575ae0eb6495a2478c575d9ef02d11fb1a70 Mon Sep 17 00:00:00 2001 From: "Alejandro Z. Tomsic" Date: Thu, 17 Sep 2015 18:25:16 +0200 Subject: [PATCH 051/426] changed certification --- src/crdt_bcounter.erl | 46 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/crdt_bcounter.erl b/src/crdt_bcounter.erl index 73fcf0663..2c4875b07 100644 --- a/src/crdt_bcounter.erl +++ b/src/crdt_bcounter.erl @@ -16,13 +16,13 @@ %% API -export([new/0, - localPermissions/2, - permissions/1, - value/1, - generate_downstream/3, - update/2, - to_binary/1, - from_binary/1]). + localPermissions/2, + permissions/1, + value/1, + generate_downstream/3, + update/2, + to_binary/1, + from_binary/1, is_operation/1]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -154,6 +154,28 @@ to_binary(C) -> term_to_binary(C). -spec from_binary(binary()) -> bcounter(). from_binary(<>) -> binary_to_term(B). +%% @doc The following operation verifies +%% that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(Operation) -> + case Operation of + {decrement, Number} -> + is_integer(Number) and (Number >= 0); + {increment, Number} -> + is_integer(Number) and (Number >= 0); + {transfer, Number, _} -> + is_integer(Number) and (Number >= 0); + {{decrement, Number}, _} -> + is_integer(Number) and (Number >= 0); + {{increment, Number}, _} -> + is_integer(Number) and (Number >= 0); + {{transfer, Number, _}, _} -> + is_integer(Number) and (Number >= 0); + _ -> + false + end. + + %% =================================================================== %% EUnit tests %% =================================================================== @@ -256,4 +278,14 @@ binary_test() -> %% Assert marshaling and unmarshaling holds the same `bcounter()'. B = to_binary(Counter3), ?assertEqual(Counter3, from_binary(B)). + +is_operation_test() -> + ?assertEqual(true, is_operation({transfer, 2, r2})), + ?assertEqual(true, is_operation({increment, 50})), + ?assertEqual(false, is_operation(increment)), + ?assertEqual(true, is_operation({decrement, 50})), + ?assertEqual(false, is_operation(decrement)), + ?assertEqual(false, is_operation({anything, [1,2,3]})). + + -endif. \ No newline at end of file From 1d5ba000a6bc84bdfae1aa05b607631cad8b8a61 Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Wed, 23 Sep 2015 13:11:37 +0200 Subject: [PATCH 052/426] Update crdt_bcounter.erl --- src/crdt_bcounter.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/crdt_bcounter.erl b/src/crdt_bcounter.erl index 2c4875b07..3b1341507 100644 --- a/src/crdt_bcounter.erl +++ b/src/crdt_bcounter.erl @@ -22,7 +22,8 @@ generate_downstream/3, update/2, to_binary/1, - from_binary/1, is_operation/1]). + from_binary/1, + is_operation/1]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -288,4 +289,4 @@ is_operation_test() -> ?assertEqual(false, is_operation({anything, [1,2,3]})). --endif. \ No newline at end of file +-endif. From f22f4979c49f68a72ce3f1d596c342e02382f087 Mon Sep 17 00:00:00 2001 From: "Alejandro Z. Tomsic" Date: Wed, 23 Sep 2015 15:04:09 +0200 Subject: [PATCH 053/426] changed ocurrences of and by andalso --- src/crdt_bcounter.erl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/crdt_bcounter.erl b/src/crdt_bcounter.erl index 3b1341507..56eb1d8eb 100644 --- a/src/crdt_bcounter.erl +++ b/src/crdt_bcounter.erl @@ -161,17 +161,17 @@ from_binary(<>) -> binary_to_term(B). is_operation(Operation) -> case Operation of {decrement, Number} -> - is_integer(Number) and (Number >= 0); + is_integer(Number) andalso (Number >= 0); {increment, Number} -> - is_integer(Number) and (Number >= 0); + is_integer(Number) andalso (Number >= 0); {transfer, Number, _} -> - is_integer(Number) and (Number >= 0); + is_integer(Number) andalso (Number >= 0); {{decrement, Number}, _} -> - is_integer(Number) and (Number >= 0); + is_integer(Number) andalso (Number >= 0); {{increment, Number}, _} -> - is_integer(Number) and (Number >= 0); + is_integer(Number) andalso (Number >= 0); {{transfer, Number, _}, _} -> - is_integer(Number) and (Number >= 0); + is_integer(Number) andalso (Number >= 0); _ -> false end. From 42ca8c9298caf73b69fe5a6cda6a51a5b850db3f Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 27 Aug 2015 16:01:06 +0200 Subject: [PATCH 054/426] created crdt_rga.erl file --- src/crdt_rga.erl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/crdt_rga.erl diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl new file mode 100644 index 000000000..1745765fc --- /dev/null +++ b/src/crdt_rga.erl @@ -0,0 +1,18 @@ +%% @doc +%% +%% An operation-based Replicated Growable Array CRDT. +%% +%% As the data structure is operation-based, to issue an operation, one should +%% first call `generate_downstream/3', to get the downstream version of the +%% operation, and then call `update/2'. +%% +%% It provides two operations: insert, which adds an element to the RGA, and delete, +%% which removes an element from the RGA. +%% +%% This implementation is based on the paper cited below. +%% +%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of +%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ +%% +%% @end +-module(crdt_rga). From 131c2846d7fb5aeff1c2096631e0522abf12487e Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 13:57:07 +0200 Subject: [PATCH 055/426] first RGA version with local insert and delete --- src/crdt_rga.erl | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 1745765fc..1f68b9ebf 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -16,3 +16,48 @@ %% %% @end -module(crdt_rga). + +-export([new/0, update/2]). + +-type vertex() :: {any(), any()}. + +-type rga_op() :: {addRight, vertex(), atom()} | {remove, vertex()}. + +-type rga_result() :: {ok, vertex(), rga()} | rga() . + +-type rga() :: list(). + +-spec new() -> rga(). +new() -> + []. + +-spec update(rga_op(), rga()) -> rga_result(). +update({addRight, Vertex, Value}, Rga) -> + recursive_insert(Vertex, Value, Rga, []); +update({remove, Vertex}, Rga) -> + recursive_remove(Vertex, Rga, []). + +recursive_insert(_, Value, [], []) -> + Inserted = {Value, os:timestamp()}, + {ok, Inserted, [Inserted]}; +recursive_insert(Vertex, Value, [Vertex | T], L) -> + add_element({Value, os:timestamp()}, T, L ++ [Vertex]); +recursive_insert(Vertex, Value, [H | T], L) -> + recursive_insert(Vertex, Value, T, L ++ [H]). + +add_element({Value, TimeStamp}, [{Value1, TimeStamp1} | T], L) -> + case TimeStamp >= TimeStamp1 of + true -> + {ok, {Value, TimeStamp}, L ++ [{Value, TimeStamp}] ++ [{Value1, TimeStamp1} | T]}; + _ -> + add_element({Value, TimeStamp}, T, L ++ [{Value1, TimeStamp1}]) + end; +add_element(Insert, [], L) -> + {ok, Insert, L ++ [Insert]}. + +recursive_remove(_, [], L) -> + L; +recursive_remove({Value, TimeStamp}, [{Value, TimeStamp} | T], L) -> + L ++ [{deleted, TimeStamp}] ++ T; +recursive_remove(Vertex, [H | T], L) -> + recursive_remove(Vertex, T, L ++ [H]). From c15cb3b88ce046c0431a376f014e92a2c49fe416 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 14:31:26 +0200 Subject: [PATCH 056/426] Test for new method --- src/crdt_rga.erl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 1f68b9ebf..75d26e120 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -19,6 +19,10 @@ -export([new/0, update/2]). +%% -ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +%% -endif. + -type vertex() :: {any(), any()}. -type rga_op() :: {addRight, vertex(), atom()} | {remove, vertex()}. @@ -61,3 +65,11 @@ recursive_remove({Value, TimeStamp}, [{Value, TimeStamp} | T], L) -> L ++ [{deleted, TimeStamp}] ++ T; recursive_remove(Vertex, [H | T], L) -> recursive_remove(Vertex, T, L ++ [H]). + +-ifdef(TEST). +new_test() -> + ?assertEqual([], new()). +-endif. + + + From 751bcb7bd82d2fd0aa9e9eb5f7485e7f6b5534e9 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 14:31:56 +0200 Subject: [PATCH 057/426] Tests for insert method --- src/crdt_rga.erl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 75d26e120..563076f2d 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -69,6 +69,25 @@ recursive_remove(Vertex, [H | T], L) -> -ifdef(TEST). new_test() -> ?assertEqual([], new()). + +insert_returns_same_element_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + ?assertEqual([V1], L1). + +consecutive_inserts_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V2, L2} = update({addRight, V1, 2}, L1), + {ok, _, L3} = update({addRight, V2, 3}, L2), + ?assertMatch([{1, _}, {2, _}, {3, _}], L3). + +insert_in_the_middle_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, _, L2} = update({addRight, V1, 2}, L1), + {ok, _, L3} = update({addRight, V1, 3}, L2), + ?assertMatch([{1, _}, {3, _}, {2, _}], L3). -endif. From 11c2deb34701a87360880df1bca68966bd915329 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 14:36:54 +0200 Subject: [PATCH 058/426] Tests for remove method --- src/crdt_rga.erl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 563076f2d..c693e505d 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -88,6 +88,30 @@ insert_in_the_middle_test() -> {ok, _, L2} = update({addRight, V1, 2}, L1), {ok, _, L3} = update({addRight, V1, 3}, L2), ?assertMatch([{1, _}, {3, _}, {2, _}], L3). + +remove_first_element_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V2, L2} = update({addRight, V1, 2}, L1), + {ok, _, L3} = update({addRight, V2, 3}, L2), + L4 = update({remove, V1}, L3), + ?assertMatch([{deleted, _}, {2, _}, {3, _}], L4). + +remove_middle_element_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V2, L2} = update({addRight, V1, 2}, L1), + {ok, _, L3} = update({addRight, V2, 3}, L2), + L4 = update({remove, V2}, L3), + ?assertMatch([{1, _}, {deleted, _}, {3, _}], L4). + +remove_last_element_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V2, L2} = update({addRight, V1, 2}, L1), + {ok, V3, L3} = update({addRight, V2, 3}, L2), + L4 = update({remove, V3}, L3), + ?assertMatch([{1, _}, {2, _}, {deleted, _}], L4). -endif. From 597ddd19764832d6514ca9f14ca617dbad6eeec1 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 14:52:06 +0200 Subject: [PATCH 059/426] Added purge tombstones method --- src/crdt_rga.erl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index c693e505d..542bb1edc 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -17,7 +17,7 @@ %% @end -module(crdt_rga). --export([new/0, update/2]). +-export([new/0, update/2, purge_tombstones/1]). %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -66,6 +66,15 @@ recursive_remove({Value, TimeStamp}, [{Value, TimeStamp} | T], L) -> recursive_remove(Vertex, [H | T], L) -> recursive_remove(Vertex, T, L ++ [H]). +purge_tombstones(Rga) -> + lists:foldl(fun({Value, TimeStamp}, L) -> + case Value == deleted of + true -> L; + _ -> L ++ [{Value, TimeStamp}] + end + end, [], Rga). + + -ifdef(TEST). new_test() -> ?assertEqual([], new()). From 6be142e94500278a9400e0ef6e0bda5e4ab84332 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 14:53:46 +0200 Subject: [PATCH 060/426] Tests for purge tombstones method --- src/crdt_rga.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 542bb1edc..1b76b8aad 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -121,6 +121,16 @@ remove_last_element_test() -> {ok, V3, L3} = update({addRight, V2, 3}, L2), L4 = update({remove, V3}, L3), ?assertMatch([{1, _}, {2, _}, {deleted, _}], L4). + +pruge_tombstones_test() -> + L = new(), + {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V2, L2} = update({addRight, V1, 2}, L1), + {ok, _, L3} = update({addRight, V2, 3}, L2), + L4 = update({remove, V2}, L3), + L5 = purge_tombstones(L4), + ?assertMatch([{1, _}, {3, _}], L5). + -endif. From c4f7f52687dc0df373159ad2ac4dba471690d432 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 31 Aug 2015 15:07:01 +0200 Subject: [PATCH 061/426] Added Doc --- src/crdt_rga.erl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 1b76b8aad..d25191232 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -35,12 +35,16 @@ new() -> []. +%% @doc This method takes in an rga operation and an rga to perform the operation. +%% It returns either the added Vertex and the new rga in case of an insert, and the new rga in the case of a remove. -spec update(rga_op(), rga()) -> rga_result(). update({addRight, Vertex, Value}, Rga) -> recursive_insert(Vertex, Value, Rga, []); update({remove, Vertex}, Rga) -> recursive_remove(Vertex, Rga, []). +%% Private +%% @doc recursively looks for the Vertex where the new element should be put to the right of. recursive_insert(_, Value, [], []) -> Inserted = {Value, os:timestamp()}, {ok, Inserted, [Inserted]}; @@ -49,6 +53,8 @@ recursive_insert(Vertex, Value, [Vertex | T], L) -> recursive_insert(Vertex, Value, [H | T], L) -> recursive_insert(Vertex, Value, T, L ++ [H]). +%% Private +%% @doc the place for the insertion has been found, so now the TimeStamps are compared to see where to insert. add_element({Value, TimeStamp}, [{Value1, TimeStamp1} | T], L) -> case TimeStamp >= TimeStamp1 of true -> @@ -59,6 +65,8 @@ add_element({Value, TimeStamp}, [{Value1, TimeStamp1} | T], L) -> add_element(Insert, [], L) -> {ok, Insert, L ++ [Insert]}. +%% Private +%% @doc recursively looks for the Vertex to be removed. Once it is found, it is marked as "deleted", erasing its value. recursive_remove(_, [], L) -> L; recursive_remove({Value, TimeStamp}, [{Value, TimeStamp} | T], L) -> @@ -66,6 +74,7 @@ recursive_remove({Value, TimeStamp}, [{Value, TimeStamp} | T], L) -> recursive_remove(Vertex, [H | T], L) -> recursive_remove(Vertex, T, L ++ [H]). +%% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. purge_tombstones(Rga) -> lists:foldl(fun({Value, TimeStamp}, L) -> case Value == deleted of From 0068a9e04d683b9dead149b63c2c9bc10b0ac52f Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 3 Sep 2015 10:01:26 +0200 Subject: [PATCH 062/426] refactor for marking deletions correctly --- src/crdt_rga.erl | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index d25191232..17c199222 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -23,11 +23,11 @@ -include_lib("eunit/include/eunit.hrl"). %% -endif. --type vertex() :: {any(), any()}. +-type vertex() :: {atom(), any(), number()}. -type rga_op() :: {addRight, vertex(), atom()} | {remove, vertex()}. --type rga_result() :: {ok, vertex(), rga()} | rga() . +-type rga_result() :: {ok, vertex(), rga()} | rga(). -type rga() :: list(). @@ -46,21 +46,21 @@ update({remove, Vertex}, Rga) -> %% Private %% @doc recursively looks for the Vertex where the new element should be put to the right of. recursive_insert(_, Value, [], []) -> - Inserted = {Value, os:timestamp()}, + Inserted = {ok, Value, os:timestamp()}, {ok, Inserted, [Inserted]}; recursive_insert(Vertex, Value, [Vertex | T], L) -> - add_element({Value, os:timestamp()}, T, L ++ [Vertex]); + add_element({ok, Value, os:timestamp()}, T, L ++ [Vertex]); recursive_insert(Vertex, Value, [H | T], L) -> recursive_insert(Vertex, Value, T, L ++ [H]). %% Private %% @doc the place for the insertion has been found, so now the TimeStamps are compared to see where to insert. -add_element({Value, TimeStamp}, [{Value1, TimeStamp1} | T], L) -> +add_element({Status, Value, TimeStamp}, [{Status1, Value1, TimeStamp1} | T], L) -> case TimeStamp >= TimeStamp1 of true -> - {ok, {Value, TimeStamp}, L ++ [{Value, TimeStamp}] ++ [{Value1, TimeStamp1} | T]}; + {ok, {Status, Value, TimeStamp}, L ++ [{Status, Value, TimeStamp}] ++ [{Status1, Value1, TimeStamp1} | T]}; _ -> - add_element({Value, TimeStamp}, T, L ++ [{Value1, TimeStamp1}]) + add_element({Status, Value, TimeStamp}, T, L ++ [{Status1, Value1, TimeStamp1}]) end; add_element(Insert, [], L) -> {ok, Insert, L ++ [Insert]}. @@ -69,17 +69,17 @@ add_element(Insert, [], L) -> %% @doc recursively looks for the Vertex to be removed. Once it is found, it is marked as "deleted", erasing its value. recursive_remove(_, [], L) -> L; -recursive_remove({Value, TimeStamp}, [{Value, TimeStamp} | T], L) -> - L ++ [{deleted, TimeStamp}] ++ T; +recursive_remove({_, Value, TimeStamp}, [{_, Value, TimeStamp} | T], L) -> + L ++ [{deleted, Value, TimeStamp}] ++ T; recursive_remove(Vertex, [H | T], L) -> recursive_remove(Vertex, T, L ++ [H]). %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. purge_tombstones(Rga) -> - lists:foldl(fun({Value, TimeStamp}, L) -> - case Value == deleted of + lists:foldl(fun({Status, Value, TimeStamp}, L) -> + case Status == deleted of true -> L; - _ -> L ++ [{Value, TimeStamp}] + _ -> L ++ [{Status, Value, TimeStamp}] end end, [], Rga). @@ -90,22 +90,22 @@ new_test() -> insert_returns_same_element_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), ?assertEqual([V1], L1). consecutive_inserts_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), {ok, V2, L2} = update({addRight, V1, 2}, L1), {ok, _, L3} = update({addRight, V2, 3}, L2), - ?assertMatch([{1, _}, {2, _}, {3, _}], L3). + ?assertMatch([{ok, 1, _}, {ok, 2, _}, {ok, 3, _}], L3). insert_in_the_middle_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), {ok, _, L2} = update({addRight, V1, 2}, L1), {ok, _, L3} = update({addRight, V1, 3}, L2), - ?assertMatch([{1, _}, {3, _}, {2, _}], L3). + ?assertMatch([{ok, 1, _}, {ok, 3, _}, {ok, 2, _}], L3). remove_first_element_test() -> L = new(), @@ -113,32 +113,32 @@ remove_first_element_test() -> {ok, V2, L2} = update({addRight, V1, 2}, L1), {ok, _, L3} = update({addRight, V2, 3}, L2), L4 = update({remove, V1}, L3), - ?assertMatch([{deleted, _}, {2, _}, {3, _}], L4). + ?assertMatch([{deleted, 1, _}, {ok, 2, _}, {ok, 3, _}], L4). remove_middle_element_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), {ok, V2, L2} = update({addRight, V1, 2}, L1), {ok, _, L3} = update({addRight, V2, 3}, L2), L4 = update({remove, V2}, L3), - ?assertMatch([{1, _}, {deleted, _}, {3, _}], L4). + ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 3, _}], L4). remove_last_element_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), {ok, V2, L2} = update({addRight, V1, 2}, L1), {ok, V3, L3} = update({addRight, V2, 3}, L2), L4 = update({remove, V3}, L3), - ?assertMatch([{1, _}, {2, _}, {deleted, _}], L4). + ?assertMatch([{ok, 1, _}, {ok, 2, _}, {deleted, 3, _}], L4). pruge_tombstones_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), + {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), {ok, V2, L2} = update({addRight, V1, 2}, L1), {ok, _, L3} = update({addRight, V2, 3}, L2), L4 = update({remove, V2}, L3), L5 = purge_tombstones(L4), - ?assertMatch([{1, _}, {3, _}], L5). + ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). -endif. From c7ca076635b5c36a710b0adcdb6366a2d6e6f607 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 3 Sep 2015 11:29:45 +0200 Subject: [PATCH 063/426] generate_downstream method --- src/crdt_rga.erl | 176 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 123 insertions(+), 53 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 17c199222..49d1eb981 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -17,7 +17,7 @@ %% @end -module(crdt_rga). --export([new/0, update/2, purge_tombstones/1]). +-export([new/0, update/2, purge_tombstones/1, generate_downstream/3]). %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -25,118 +25,188 @@ -type vertex() :: {atom(), any(), number()}. --type rga_op() :: {addRight, vertex(), atom()} | {remove, vertex()}. +-type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, vertex()}. --type rga_result() :: {ok, vertex(), rga()} | rga(). +-type rga_op() :: {addRight, any(), number()} | {remove, number()}. + +-type rga_result() :: {ok, rga}. -type rga() :: list(). +-type actor() :: riak_dt:actor(). + -spec new() -> rga(). new() -> []. +%% @doc generate downstream operations. +%% If the operation is addRight, generates a unique token for the new element. +%% If the operation is remove, fetches the vertex of the element to be removed. +-spec generate_downstream(rga_op(), actor(), rga()) -> {ok, rga_downstream_op()}. +generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> + case length(Rga) of + 0 -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; + _ -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} + end; +generate_downstream({remove, Position}, _Actor, Rga) -> + {ok, {remove, lists:nth(Position, Rga)}}. + %% @doc This method takes in an rga operation and an rga to perform the operation. %% It returns either the added Vertex and the new rga in case of an insert, and the new rga in the case of a remove. --spec update(rga_op(), rga()) -> rga_result(). -update({addRight, Vertex, Value}, Rga) -> - recursive_insert(Vertex, Value, Rga, []); +-spec update(rga_downstream_op(), rga()) -> rga_result(). +update({addRight, RightVertex, NewVertex}, Rga) -> + recursive_insert(RightVertex, NewVertex, Rga, []); update({remove, Vertex}, Rga) -> recursive_remove(Vertex, Rga, []). %% Private %% @doc recursively looks for the Vertex where the new element should be put to the right of. -recursive_insert(_, Value, [], []) -> - Inserted = {ok, Value, os:timestamp()}, - {ok, Inserted, [Inserted]}; -recursive_insert(Vertex, Value, [Vertex | T], L) -> - add_element({ok, Value, os:timestamp()}, T, L ++ [Vertex]); -recursive_insert(Vertex, Value, [H | T], L) -> - recursive_insert(Vertex, Value, T, L ++ [H]). +recursive_insert(_, NewVertex, [], []) -> + {ok, [NewVertex]}; +recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> + add_element(NewVertex, T, L ++ [RightVertex]); +recursive_insert(RightVertex, NewVertex, [H | T], L) -> + recursive_insert(RightVertex, NewVertex, T, L ++ [H]). %% Private -%% @doc the place for the insertion has been found, so now the TimeStamps are compared to see where to insert. -add_element({Status, Value, TimeStamp}, [{Status1, Value1, TimeStamp1} | T], L) -> - case TimeStamp >= TimeStamp1 of +%% @doc the place for the insertion has been found, so now the UIDs are compared to see where to insert. +add_element({Status, Value, UID}, [{Status1, Value1, UID1} | T], L) -> + case UID >= UID1 of true -> - {ok, {Status, Value, TimeStamp}, L ++ [{Status, Value, TimeStamp}] ++ [{Status1, Value1, TimeStamp1} | T]}; + {ok, L ++ [{Status, Value, UID}] ++ [{Status1, Value1, UID1} | T]}; _ -> - add_element({Status, Value, TimeStamp}, T, L ++ [{Status1, Value1, TimeStamp1}]) + add_element({Status, Value, UID}, T, L ++ [{Status1, Value1, UID1}]) end; add_element(Insert, [], L) -> - {ok, Insert, L ++ [Insert]}. + {ok, L ++ [Insert]}. %% Private %% @doc recursively looks for the Vertex to be removed. Once it is found, it is marked as "deleted", erasing its value. recursive_remove(_, [], L) -> - L; -recursive_remove({_, Value, TimeStamp}, [{_, Value, TimeStamp} | T], L) -> - L ++ [{deleted, Value, TimeStamp}] ++ T; + {ok, L}; +recursive_remove({_, Value, UID}, [{_, Value, UID} | T], L) -> + {ok, L ++ [{deleted, Value, UID}] ++ T}; recursive_remove(Vertex, [H | T], L) -> recursive_remove(Vertex, T, L ++ [H]). %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. purge_tombstones(Rga) -> - lists:foldl(fun({Status, Value, TimeStamp}, L) -> + lists:foldl(fun({Status, Value, UID}, L) -> case Status == deleted of - true -> L; - _ -> L ++ [{Status, Value, TimeStamp}] + true -> L; + _ -> L ++ [{Status, Value, UID}] end end, [], Rga). +%% @doc generate a unique identifier (best-effort). +unique() -> + crypto:strong_rand_bytes(20). + -ifdef(TEST). + new_test() -> ?assertEqual([], new()). -insert_returns_same_element_test() -> +generate_downstream_empty_rga_test() -> L = new(), - {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), - ?assertEqual([V1], L1). + {ok, DownstreamOp} = generate_downstream({addRight, 4, 1}, 1, L), + ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). -consecutive_inserts_test() -> +generate_downstream_non_empty_rga_test() -> L = new(), - {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), - {ok, V2, L2} = update({addRight, V1, 2}, L1), - {ok, _, L3} = update({addRight, V2, 3}, L2), - ?assertMatch([{ok, 1, _}, {ok, 2, _}, {ok, 3, _}], L3). + {ok, DownstreamOp} = generate_downstream({addRight, 4, 1}, 1, L), + {ok, L1} = update(DownstreamOp, L), + {ok, DownstreamOp1} = generate_downstream({addRight, 3, 1}, 1, L1), + ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). + +add_right_in_empty_rga_test() -> + L = new(), + {ok, DownstreamOp} = generate_downstream({addRight, 1, 1}, 1, L), + {ok, L1} = update(DownstreamOp, L), + ?assertMatch([{ok, 1, _}], L1). + +add_right_in_non_empty_rga_test() -> + L = new(), + {ok, DownstreamOp} = generate_downstream({addRight, 1, 1}, 1, L), + {ok, L1} = update(DownstreamOp, L), + {ok, DownstreamOp1} = generate_downstream({addRight, 2, 1}, 1, L1), + {ok, L2} = update(DownstreamOp1, L1), + ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). + +%% In the tests that follow, the values of generate_downstream are placed by hand so +%% the intended scenarios can be correctly tested, not depending on the unique() function. insert_in_the_middle_test() -> L = new(), - {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), - {ok, _, L2} = update({addRight, V1, 2}, L1), - {ok, _, L3} = update({addRight, V1, 3}, L2), - ?assertMatch([{ok, 1, _}, {ok, 3, _}, {ok, 2, _}], L3). + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + ?assertMatch([{ok, 1, _}, {ok, 2, _}, {ok, 3, _}], L3). remove_first_element_test() -> L = new(), - {ok, V1, L1} = update({addRight, {0, 0}, 1}, L), - {ok, V2, L2} = update({addRight, V1, 2}, L1), - {ok, _, L3} = update({addRight, V2, 3}, L2), - L4 = update({remove, V1}, L3), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 1}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), ?assertMatch([{deleted, 1, _}, {ok, 2, _}, {ok, 3, _}], L4). remove_middle_element_test() -> L = new(), - {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), - {ok, V2, L2} = update({addRight, V1, 2}, L1), - {ok, _, L3} = update({addRight, V2, 3}, L2), - L4 = update({remove, V2}, L3), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 3, _}], L4). remove_last_element_test() -> L = new(), - {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), - {ok, V2, L2} = update({addRight, V1, 2}, L1), - {ok, V3, L3} = update({addRight, V2, 3}, L2), - L4 = update({remove, V3}, L3), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 3}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), ?assertMatch([{ok, 1, _}, {ok, 2, _}, {deleted, 3, _}], L4). +insert_right_of_a_remove_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 4}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), + DownstreamOp5 = {addRight, {deleted, 2, 4}, {ok, 4, 3}}, + {ok, L5} = update(DownstreamOp5, L4), + ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 4, _}, {ok, 3, _}], L5). + pruge_tombstones_test() -> L = new(), - {ok, V1, L1} = update({addRight, {ok, 0, 0}, 1}, L), - {ok, V2, L2} = update({addRight, V1, 2}, L1), - {ok, _, L3} = update({addRight, V2, 3}, L2), - L4 = update({remove, V2}, L3), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), L5 = purge_tombstones(L4), ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). From 6d998df7f63ca49f3e5fc39ddd7f20fd093c7f7f Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 3 Sep 2015 11:32:28 +0200 Subject: [PATCH 064/426] export rga types --- src/crdt_rga.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 49d1eb981..eef2da9ab 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -19,6 +19,8 @@ -export([new/0, update/2, purge_tombstones/1, generate_downstream/3]). +-export_type([rga/0, rga_op/0, rga_downstream_op/0]). + %% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). %% -endif. From 30f110ad0f15ac988427b07b28c14b1ef842aa7f Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 3 Sep 2015 13:50:17 +0200 Subject: [PATCH 065/426] performance improvements --- src/crdt_rga.erl | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index eef2da9ab..f9f6fca13 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -66,39 +66,40 @@ update({remove, Vertex}, Rga) -> recursive_insert(_, NewVertex, [], []) -> {ok, [NewVertex]}; recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> - add_element(NewVertex, T, L ++ [RightVertex]); + add_element(NewVertex, T, [RightVertex | L]); recursive_insert(RightVertex, NewVertex, [H | T], L) -> - recursive_insert(RightVertex, NewVertex, T, L ++ [H]). + recursive_insert(RightVertex, NewVertex, T, [H | L]). %% Private %% @doc the place for the insertion has been found, so now the UIDs are compared to see where to insert. add_element({Status, Value, UID}, [{Status1, Value1, UID1} | T], L) -> case UID >= UID1 of true -> - {ok, L ++ [{Status, Value, UID}] ++ [{Status1, Value1, UID1} | T]}; + {ok, lists:reverse(L) ++ [{Status, Value, UID}] ++ [{Status1, Value1, UID1} | T]}; _ -> - add_element({Status, Value, UID}, T, L ++ [{Status1, Value1, UID1}]) + add_element({Status, Value, UID}, T, [{Status1, Value1, UID1} | L]) end; add_element(Insert, [], L) -> - {ok, L ++ [Insert]}. + {ok, lists:reverse([Insert | L])}. %% Private %% @doc recursively looks for the Vertex to be removed. Once it is found, it is marked as "deleted", erasing its value. recursive_remove(_, [], L) -> {ok, L}; recursive_remove({_, Value, UID}, [{_, Value, UID} | T], L) -> - {ok, L ++ [{deleted, Value, UID}] ++ T}; + {ok, lists:reverse(L) ++ [{deleted, Value, UID}] ++ T}; recursive_remove(Vertex, [H | T], L) -> - recursive_remove(Vertex, T, L ++ [H]). + recursive_remove(Vertex, T, [H | L]). %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. purge_tombstones(Rga) -> - lists:foldl(fun({Status, Value, UID}, L) -> + L = lists:foldl(fun({Status, Value, UID}, L) -> case Status == deleted of true -> L; - _ -> L ++ [{Status, Value, UID}] + _ -> [{Status, Value, UID} | L] end - end, [], Rga). + end, [], Rga), + lists:reverse(L). %% @doc generate a unique identifier (best-effort). unique() -> From 1926ca981e6c345eb4e39a9422a94361aed93739 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 3 Sep 2015 13:55:44 +0200 Subject: [PATCH 066/426] added specs missing --- src/crdt_rga.erl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index f9f6fca13..0ae4120c9 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -63,6 +63,7 @@ update({remove, Vertex}, Rga) -> %% Private %% @doc recursively looks for the Vertex where the new element should be put to the right of. +-spec recursive_insert(vertex(), vertex(), rga(), list()) -> rga_result(). recursive_insert(_, NewVertex, [], []) -> {ok, [NewVertex]}; recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> @@ -72,6 +73,7 @@ recursive_insert(RightVertex, NewVertex, [H | T], L) -> %% Private %% @doc the place for the insertion has been found, so now the UIDs are compared to see where to insert. +-spec add_element(vertex(), rga(), list()) -> rga_result(). add_element({Status, Value, UID}, [{Status1, Value1, UID1} | T], L) -> case UID >= UID1 of true -> @@ -84,6 +86,7 @@ add_element(Insert, [], L) -> %% Private %% @doc recursively looks for the Vertex to be removed. Once it is found, it is marked as "deleted", erasing its value. +-spec recursive_remove(vertex(), rga(), list()) -> rga_result(). recursive_remove(_, [], L) -> {ok, L}; recursive_remove({_, Value, UID}, [{_, Value, UID} | T], L) -> @@ -92,6 +95,7 @@ recursive_remove(Vertex, [H | T], L) -> recursive_remove(Vertex, T, [H | L]). %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. +-spec purge_tombstones(rga()) -> rga_result(). purge_tombstones(Rga) -> L = lists:foldl(fun({Status, Value, UID}, L) -> case Status == deleted of @@ -99,7 +103,7 @@ purge_tombstones(Rga) -> _ -> [{Status, Value, UID} | L] end end, [], Rga), - lists:reverse(L). + {ok, lists:reverse(L)}. %% @doc generate a unique identifier (best-effort). unique() -> @@ -210,7 +214,7 @@ pruge_tombstones_test() -> {ok, L3} = update(DownstreamOp3, L2), {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), {ok, L4} = update(DownstreamOp4, L3), - L5 = purge_tombstones(L4), + {ok, L5} = purge_tombstones(L4), ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). -endif. From 04857526ec7b24366dba37f55074d8bf8c4c3df7 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 7 Sep 2015 15:54:19 +0200 Subject: [PATCH 067/426] Added value method to RGA and fixed tests --- src/crdt_rga.erl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 0ae4120c9..3c2f3b6f4 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -17,13 +17,13 @@ %% @end -module(crdt_rga). --export([new/0, update/2, purge_tombstones/1, generate_downstream/3]). +-export([new/0, update/2, purge_tombstones/1, generate_downstream/3, value/1]). -export_type([rga/0, rga_op/0, rga_downstream_op/0]). -%% -ifdef(TEST). +-ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -%% -endif. +-endif. -type vertex() :: {atom(), any(), number()}. @@ -53,6 +53,11 @@ generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> generate_downstream({remove, Position}, _Actor, Rga) -> {ok, {remove, lists:nth(Position, Rga)}}. +%% @doc given an RGA, returns the same RGA, as it represents its own value. +-spec value(rga()) -> rga(). +value(Rga) -> + Rga. + %% @doc This method takes in an rga operation and an rga to perform the operation. %% It returns either the added Vertex and the new rga in case of an insert, and the new rga in the case of a remove. -spec update(rga_downstream_op(), rga()) -> rga_result(). From eac2cc2da6d6db51fadadc9fcfbb2f4688fc2aec Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 7 Sep 2015 16:59:06 +0200 Subject: [PATCH 068/426] updates in two replicas eunit test --- src/crdt_rga.erl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 3c2f3b6f4..4bdff67d0 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -71,6 +71,8 @@ update({remove, Vertex}, Rga) -> -spec recursive_insert(vertex(), vertex(), rga(), list()) -> rga_result(). recursive_insert(_, NewVertex, [], []) -> {ok, [NewVertex]}; +recursive_insert({ok, 0, 0}, NewVertex, L, []) -> + add_element(NewVertex, L, []); recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> add_element(NewVertex, T, [RightVertex | L]); recursive_insert(RightVertex, NewVertex, [H | T], L) -> @@ -222,6 +224,26 @@ pruge_tombstones_test() -> {ok, L5} = purge_tombstones(L4), ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). +%% This test creates two RGAs and performs updates, checking they reach +%% the same final state after the two updates are aplied in both replicas. +concurrent_updates_in_two_replicas_test() -> + R1_0 = new(), + R2_0 = new(), + {ok, DownstreamOp1} = generate_downstream({addRight, 1, 1}, 1, R1_0), + {ok, DownstreamOp2} = generate_downstream({addRight, 2, 1}, 1, R2_0), + {ok, R1_1} = update(DownstreamOp1, R1_0), + {ok, R2_1} = update(DownstreamOp2, R2_0), + {ok, R1_2} = update(DownstreamOp2, R1_1), + {ok, R2_2} = update(DownstreamOp1, R2_1), + ?assertEqual(R1_2, R2_2), + {ok, DownstreamOp3} = generate_downstream({addRight, 3, 2}, 1, R1_2), + {ok, DownstreamOp4} = generate_downstream({addRight, 4, 2}, 1, R2_2), + {ok, R1_3} = update(DownstreamOp3, R1_2), + {ok, R2_3} = update(DownstreamOp4, R2_2), + {ok, R1_4} = update(DownstreamOp4, R1_3), + {ok, R2_4} = update(DownstreamOp3, R2_3), + ?assertEqual(R1_4, R2_4). + -endif. From 78c8ffe933acbb0a734eb94d1210ab156cc16742 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 7 Sep 2015 17:23:43 +0200 Subject: [PATCH 069/426] comments and typos fixes --- src/crdt_rga.erl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 4bdff67d0..1bc256397 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -6,7 +6,7 @@ %% first call `generate_downstream/3', to get the downstream version of the %% operation, and then call `update/2'. %% -%% It provides two operations: insert, which adds an element to the RGA, and delete, +%% It provides two operations: addRight, which adds an element to the RGA, and remove, %% which removes an element from the RGA. %% %% This implementation is based on the paper cited below. @@ -59,7 +59,7 @@ value(Rga) -> Rga. %% @doc This method takes in an rga operation and an rga to perform the operation. -%% It returns either the added Vertex and the new rga in case of an insert, and the new rga in the case of a remove. +%% It returns either the added Vertex and the new rga in case of an addRight, and the new rga in the case of a remove. -spec update(rga_downstream_op(), rga()) -> rga_result(). update({addRight, RightVertex, NewVertex}, Rga) -> recursive_insert(RightVertex, NewVertex, Rga, []); @@ -92,7 +92,8 @@ add_element(Insert, [], L) -> {ok, lists:reverse([Insert | L])}. %% Private -%% @doc recursively looks for the Vertex to be removed. Once it is found, it is marked as "deleted", erasing its value. +%% @doc recursively looks for the Vertex to be removed. Once it's found, it's marked as "deleted". +%% The Vertex is not removed from the list, to allow adding elements to its right. -spec recursive_remove(vertex(), rga(), list()) -> rga_result(). recursive_remove(_, [], L) -> {ok, L}; @@ -148,7 +149,7 @@ add_right_in_non_empty_rga_test() -> {ok, L2} = update(DownstreamOp1, L1), ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). -%% In the tests that follow, the values of generate_downstream are placed by hand so +%% In the tests that follow, the values of generate_downstream are placed by hand ,so %% the intended scenarios can be correctly tested, not depending on the unique() function. insert_in_the_middle_test() -> @@ -211,7 +212,7 @@ insert_right_of_a_remove_test() -> {ok, L5} = update(DownstreamOp5, L4), ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 4, _}, {ok, 3, _}], L5). -pruge_tombstones_test() -> +purge_tombstones_test() -> L = new(), DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, @@ -225,7 +226,7 @@ pruge_tombstones_test() -> ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). %% This test creates two RGAs and performs updates, checking they reach -%% the same final state after the two updates are aplied in both replicas. +%% the same final state after the four updates are aplied in both replicas. concurrent_updates_in_two_replicas_test() -> R1_0 = new(), R2_0 = new(), From a8f6df0c3f624bc5341010741fef0ec708819a8a Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Mon, 14 Sep 2015 10:49:41 +0200 Subject: [PATCH 070/426] riak_test init --- src/crdt_rga.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 1bc256397..0b3c72b1c 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -31,13 +31,13 @@ -type rga_op() :: {addRight, any(), number()} | {remove, number()}. --type rga_result() :: {ok, rga}. +-type rga_result() :: {ok, rga()}. -type rga() :: list(). -type actor() :: riak_dt:actor(). --spec new() -> rga(). +-spec new() -> []. new() -> []. From 6ebd96b51cc27eba3e46e36998c0b38dbba984cf Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Wed, 16 Sep 2015 15:00:47 +0200 Subject: [PATCH 071/426] cleanup --- src/antidotec_pb.erl | 30 +++++++++++++++++------------- src/antidotec_pb_socket.erl | 6 +++--- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index 154e66e87..dafc861d3 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -30,13 +30,15 @@ -define(TIMEOUT, 10000). --spec start_transaction(Pid::term(), TimeStamp::term(), TxnProperties::term()) -> {ok, term()} | {error, term()}. +-spec start_transaction(Pid::term(), TimeStamp::term(), TxnProperties::term()) + -> {ok, term()} | {error, term()}. start_transaction(Pid, TimeStamp, TxnProperties) -> - EncMsg = antidote_pb_codec:encode(start_transaction, {TimeStamp, TxnProperties}), + EncMsg = antidote_pb_codec:encode(start_transaction, + {TimeStamp, TxnProperties}), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), - case Result of + case Result of {error, timeout} -> {error, timeout}; - _ -> + _ -> case antidote_pb_codec:decode_response(Result) of {start_transaction, TxId} -> {ok, TxId}; @@ -51,9 +53,9 @@ start_transaction(Pid, TimeStamp, TxnProperties) -> abort_transaction(Pid, TxId) -> EncMsg = antidote_pb_codec:encode(abort_transaction, TxId), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), - case Result of + case Result of {error, timeout} -> {error, timeout}; - _ -> + _ -> case antidote_pb_codec:decode_response(Result) of {opresponse, ok} -> ok; {error, Reason} -> {error, Reason}; @@ -61,13 +63,14 @@ abort_transaction(Pid, TxId) -> end end. --spec commit_transaction(Pid::term(), TxId::term()) -> {ok, term()} | {error, term()}. +-spec commit_transaction(Pid::term(), TxId::term()) -> + {ok, term()} | {error, term()}. commit_transaction(Pid, TxId) -> EncMsg = antidote_pb_codec:encode(commit_transaction, TxId), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), - case Result of + case Result of {error, timeout} -> {error, timeout}; - _ -> + _ -> case antidote_pb_codec:decode_response(Result) of {commit_transaction, CommitTimeStamp} -> {ok, CommitTimeStamp}; {error, Reason} -> {error, Reason}; @@ -75,12 +78,13 @@ commit_transaction(Pid, TxId) -> end end. +%%-spec update_objects(Pid::term(), Updates::[{bound_object(), op(), op_parm()}], TxId::term()) -> ok | {error, term()}. update_objects(Pid, Updates, TxId) -> EncMsg = antidote_pb_codec: encode(update_objects, {Updates, TxId}), Result = antidotec_pb_socket: call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), - case Result of + case Result of {error, timeout} -> {error, timeout}; - _ -> + _ -> case antidote_pb_codec: decode_response(Result) of {opresponse, ok} -> ok; {error, Reason} -> {error, Reason}; @@ -91,9 +95,9 @@ update_objects(Pid, Updates, TxId) -> read_objects(Pid, Objects, TxId) -> EncMsg = antidote_pb_codec:encode(read_objects, {Objects, TxId}), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), - case Result of + case Result of {error, timeout} -> {error, timeout}; - _ -> + _ -> case antidote_pb_codec:decode_response(Result) of {read_objects, Values} -> {ok, Values}; {error, Reason} -> {error, Reason}; diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index dca34b662..d1f35dd56 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -116,7 +116,6 @@ handle_call(stop, _From, State) -> handle_info({_Proto, Sock, Data}, State=#state{active = (Active = #request{})}) -> <> = Data, Response = riak_pb_codec:decode(MsgCode, MsgData), - lager:info("Response ~p", [Response]), cancel_req_timer(Active#request.tref), _ = send_caller(Response, Active), NewState = State#state{active = undefined}, @@ -198,7 +197,6 @@ create_req_timer(Msecs, Ref) -> %% @private send_request(Request0, State) when State#state.active =:= undefined -> {Request, Pkt} = encode_request_message(Request0), - lager:info("Sending message"), case gen_tcp:send(State#state.sock, Pkt) of ok -> maybe_reply({noreply,State#state{active = Request}}); @@ -212,7 +210,9 @@ send_request(Request0, State) when State#state.active =:= undefined -> %% Unencoded Request (the normal PB client path) encode_request_message(#request{msg=Msg}=Req) -> - {Req, riak_pb_codec:encode(Msg)}. + EncMsg = riak_pb_codec:encode(Msg), + {Req, EncMsg}. + %{Req, riak_pb_codec:encode(Msg)}. %% maybe_reply({reply, Reply, State = #state{active = Request}}) -> %% NewRequest = send_caller(Reply, Request), From 3dd10aebe3bfe72a381dfd364171db5746019b09 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Wed, 16 Sep 2015 15:11:06 +0200 Subject: [PATCH 072/426] return an error when invalid_position is passed to generate downstream --- src/crdt_rga.erl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 0b3c72b1c..e42ad3a8c 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -44,11 +44,14 @@ new() -> %% @doc generate downstream operations. %% If the operation is addRight, generates a unique token for the new element. %% If the operation is remove, fetches the vertex of the element to be removed. --spec generate_downstream(rga_op(), actor(), rga()) -> {ok, rga_downstream_op()}. +-spec generate_downstream(rga_op(), actor(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> - case length(Rga) of - 0 -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; - _ -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} + case (Position < 0) or (Position > length(Rga)) of + true -> {error, {invalid_position, Position}}; + false -> case length(Rga) of + 0 -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; + _ -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} + end end; generate_downstream({remove, Position}, _Actor, Rga) -> {ok, {remove, lists:nth(Position, Rga)}}. From 77c8ee74f30b56bd92270b6c2e670a565d136630 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Wed, 16 Sep 2015 15:16:40 +0200 Subject: [PATCH 073/426] fixed tests --- src/crdt_rga.erl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index e42ad3a8c..b1161e557 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -128,25 +128,25 @@ new_test() -> generate_downstream_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 4, 1}, 1, L), + {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). generate_downstream_non_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 4, 1}, 1, L), + {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), {ok, L1} = update(DownstreamOp, L), {ok, DownstreamOp1} = generate_downstream({addRight, 3, 1}, 1, L1), ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). add_right_in_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 1, 1}, 1, L), + {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), {ok, L1} = update(DownstreamOp, L), ?assertMatch([{ok, 1, _}], L1). add_right_in_non_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 1, 1}, 1, L), + {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), {ok, L1} = update(DownstreamOp, L), {ok, DownstreamOp1} = generate_downstream({addRight, 2, 1}, 1, L1), {ok, L2} = update(DownstreamOp1, L1), @@ -233,8 +233,8 @@ purge_tombstones_test() -> concurrent_updates_in_two_replicas_test() -> R1_0 = new(), R2_0 = new(), - {ok, DownstreamOp1} = generate_downstream({addRight, 1, 1}, 1, R1_0), - {ok, DownstreamOp2} = generate_downstream({addRight, 2, 1}, 1, R2_0), + {ok, DownstreamOp1} = generate_downstream({addRight, 1, 0}, 1, R1_0), + {ok, DownstreamOp2} = generate_downstream({addRight, 2, 0}, 1, R2_0), {ok, R1_1} = update(DownstreamOp1, R1_0), {ok, R2_1} = update(DownstreamOp2, R2_0), {ok, R1_2} = update(DownstreamOp2, R1_1), From ebb57b79f1cfccd750f263aaa2cd3bcea7b30d06 Mon Sep 17 00:00:00 2001 From: Santiago Alvarez Date: Thu, 17 Sep 2015 11:11:34 +0200 Subject: [PATCH 074/426] test for invalid position --- src/crdt_rga.erl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index b1161e557..fea00ac63 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -126,6 +126,13 @@ unique() -> new_test() -> ?assertEqual([], new()). +generate_downstream_invalid_position_test() -> + L = new(), + Result1 = generate_downstream({addRight, 1, 1}, 1, L), + ?assertMatch({error, {invalid_position, 1}}, Result1), + Result2 = generate_downstream({addRight, 1, -1}, 1, L), + ?assertMatch({error, {invalid_position, -1}}, Result2). + generate_downstream_empty_rga_test() -> L = new(), {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), From 0192b823b939413e26f3b4836bda206ad34a3463 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Mon, 21 Sep 2015 11:47:21 +0200 Subject: [PATCH 075/426] support different datatypes at client side --- src/antidotec_counter.erl | 66 +++++++++++++-------------- src/antidotec_datatype.erl | 13 ++---- src/antidotec_pb.erl | 7 ++- src/antidotec_set.erl | 93 +++++++++++++------------------------- 4 files changed, 74 insertions(+), 105 deletions(-) diff --git a/src/antidotec_counter.erl b/src/antidotec_counter.erl index ba70a73f7..acca44821 100644 --- a/src/antidotec_counter.erl +++ b/src/antidotec_counter.erl @@ -23,14 +23,12 @@ -behaviour(antidotec_datatype). --export([new/1, - new/2, - message_for_get/1, +-export([new/0, new/1, value/1, - to_ops/1, + to_ops/2, is_type/1, - type/0, - dirty_value/1 + dirty_value/1, + type/0 ]). -export([increment/1, @@ -40,64 +38,62 @@ ]). -record(counter, { - key :: term(), value :: integer(), increment :: integer() }). --export_type([antidote_counter/0]). --opaque antidote_counter() :: #counter{}. +-export_type([antidotec_counter/0]). +-opaque antidotec_counter() :: #counter{}. --spec new(term()) -> antidote_counter(). -new(Key) -> - #counter{key=Key, value=0, increment=0}. +-spec new() -> antidotec_counter(). +new() -> + #counter{value=0, increment=0}. --spec new(term(), integer()) -> antidote_counter(). -new(Key, Value) -> - #counter{key=Key, value=Value, increment=0}. +-spec new(integer()) -> antidotec_counter(). +new(Value) -> + #counter{value=Value, increment=0}. --spec value(antidote_counter()) -> integer(). +-spec value(antidotec_counter()) -> integer(). value(#counter{value=Value}) -> Value. --spec dirty_value(antidote_counter()) -> integer(). +-spec dirty_value(antidotec_counter()) -> integer(). dirty_value(#counter{value=Value, increment=Increment}) -> - Value + Increment. + Value+Increment. %% @doc Increments the counter with 1 unit. --spec increment(antidote_counter()) -> antidote_counter(). +-spec increment(antidotec_counter()) -> antidotec_counter(). increment(Counter) -> increment(1, Counter). %% @doc Increments the counter with Amount units. --spec increment(integer(), antidote_counter()) -> antidote_counter(). -increment(Amount, #counter{increment=Value}=Counter) when is_integer(Amount) -> - Counter#counter{increment=Value+Amount}. +-spec increment(integer(), antidotec_counter()) -> antidotec_counter(). +increment(Amount, #counter{increment=Increment}=Counter) + when is_integer(Amount) -> + Counter#counter{increment=Increment+Amount}. %% @doc Decrements the counter by 1. --spec decrement(antidote_counter()) -> antidote_counter(). +-spec decrement(antidotec_counter()) -> antidotec_counter(). decrement(Counter) -> increment(-1, Counter). %% @doc Decrements the counter by the passed amount. --spec decrement(integer(), antidote_counter()) -> antidote_counter(). -decrement(Amount, #counter{increment=Value}=Counter) -> +-spec decrement(integer(), antidotec_counter()) -> antidotec_counter(). +decrement(Amount, #counter{increment=Value}=Counter) + when is_integer(Amount) -> Counter#counter{increment=Value-Amount}. -spec is_type(term()) -> boolean(). is_type(T) -> is_record(T, counter). --spec type() -> riak_dt_pncounter. -type() -> riak_dt_pncounter. +type() -> + counter. -to_ops(#counter{key=_Key, increment=0}) -> undefined; +to_ops(_BoundObject, #counter{increment=0}) -> []; -to_ops(#counter{key=Key, increment=Amount}) when Amount < 0 -> - [#fpbdecrementreq{key=Key, amount=-Amount}]; - -to_ops(#counter{key=Key, increment=Amount}) -> - [#fpbincrementreq{key=Key, amount=Amount}]. - -message_for_get(Key) -> #fpbgetcounterreq{key=Key}. +to_ops(BoundObject, #counter{increment=Amount}) when Amount < 0 -> + [{BoundObject, decrement, -Amount}]; +to_ops(BoundObject, #counter{increment=Amount}) -> + [{BoundObject, increment, Amount}]. diff --git a/src/antidotec_datatype.erl b/src/antidotec_datatype.erl index 941ecd29c..c469bd903 100644 --- a/src/antidotec_datatype.erl +++ b/src/antidotec_datatype.erl @@ -41,7 +41,7 @@ %% @doc Constructs a new container for the type with the specified %% value and key. This should only be used internally by the client code. --callback new(Key::byte(), Value::term()) -> datatype(). +-callback new(Value::term()) -> datatype(). %% @doc Returns the original, unmodified value of the object. This does %% not include the execution of any locally-queued operations. @@ -50,12 +50,9 @@ %% @doc Returns the local value of the object, with the local operations applied. -callback dirty_value(datatype()) -> term(). -%% @doc Returns the message to get an object of the type of this container. --callback message_for_get(binary()) -> term(). - %% @doc Extracts the list of operations to be append to the object's log. %% 'undefined' should be returned if the type is unmodified. --callback to_ops(datatype()) -> update(). +-callback to_ops(term(), datatype()) -> update(). %% @doc Determines whether the given term is the type managed by the %% container module. @@ -66,10 +63,10 @@ -callback type() -> typename(). %% @doc Returns the module name for the container of the given CRDT data-type. --spec module_for_type(riak_dt_orset | riak_dt_pncounter) -> +-spec module_for_type(set | counter) -> antidotec_counter | antidotec_set. -module_for_type(riak_dt_orset) -> antidotec_set; -module_for_type(riak_dt_pncounter) -> antidotec_counter. +module_for_type(set) -> antidotec_set; +module_for_type(counter) -> antidotec_counter. %% @doc Returns the container module name for the given term. %% Returns undefined if the module is not known. diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index dafc861d3..9f4d69e78 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -99,7 +99,12 @@ read_objects(Pid, Objects, TxId) -> {error, timeout} -> {error, timeout}; _ -> case antidote_pb_codec:decode_response(Result) of - {read_objects, Values} -> {ok, Values}; + {read_objects, Values} -> + ResObjects = lists:map(fun({Type, Val}) -> + Mod = antidotec_datatype:module_for_type(Type), + Mod:new(Val) + end, Values), + {ok, ResObjects}; {error, Reason} -> {error, Reason}; Other -> {error, Other} end diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index 51ed6e161..27e6331dc 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -23,14 +23,13 @@ -behaviour(antidotec_datatype). --export([new/1, - new/2, - message_for_get/1, +-export([new/0, + new/1, value/1, - to_ops/1, + dirty_value/1, + to_ops/2, is_type/1, - type/0, - dirty_value/1 + type/0 ]). -export([add/2, @@ -39,7 +38,6 @@ ]). -record(antidote_set, { - key :: term(), set :: set(), adds :: set(), rems :: set() @@ -54,85 +52,59 @@ -endif. --spec new(term()) -> antidote_set(). -new(Key) -> - #antidote_set{key=Key, set=sets:new(), adds=sets:new(), rems=sets:new()}. +-spec new() -> antidote_set(). +new() -> + #antidote_set{set=sets:new(), adds=sets:new(), rems=sets:new()}. --spec new(term(), list()) -> antidote_set(). -new(Key,[]) -> - #antidote_set{key=Key, set=sets:new(), adds=sets:new(), rems=sets:new()}; +-spec new(list()) -> antidote_set(). +new([]) -> + #antidote_set{set=sets:new(), adds=sets:new(), rems=sets:new()}; -new(Key, [_H | _] = List) -> +new([_H | _] = List) -> Set = lists:foldl(fun(E,S) -> sets:add_element(E,S) end,sets:new(),List), - #antidote_set{key=Key, set=Set, adds=sets:new(), rems=sets:new()}; + #antidote_set{set=Set, adds=sets:new(), rems=sets:new()}; +new(Set) -> + #antidote_set{set=Set, adds=sets:new(), rems=sets:new()}. -new(Key, Set) -> - #antidote_set{key=Key, set=Set, adds=sets:new(), rems=sets:new()}. +-spec value(antidote_set()) -> [term()]. +value(#antidote_set{set=Set}) -> sets:to_list(Set). --spec value(antidote_set()) -> set(). -value(#antidote_set{set=Set}) -> Set. - --spec dirty_value(antidote_set()) -> set(). -dirty_value(#antidote_set{set=Set, adds=Adds}) -> - sets:union(Set,Adds). +dirty_value(#antidote_set{set=Set, adds = Adds, rems=Rems}) -> + sets:to_list(sets:subtract(sets:union(Set, Adds), Rems)). %% @doc Adds an element to the local set container. -spec add(term(), antidote_set()) -> antidote_set(). -add(Elem, #antidote_set{set=Set, adds=Adds}=Fset) -> - case sets:is_element(Elem, Set) of - false -> Fset#antidote_set{adds=sets:add_element(Elem,Adds)}; - true -> Fset - end. +add(Elem, #antidote_set{adds=Adds}=Fset) -> + Fset#antidote_set{adds=sets:add_element(Elem,Adds)}. + -spec remove(term(), antidote_set()) -> antidote_set(). -remove(Elem, #antidote_set{set=Set, adds=Adds, rems=Rems}=Fset) -> - case sets:is_element(Elem, Adds) of - true -> Fset#antidote_set{adds=sets:del_element(Elem,Adds)}; - false -> - case sets:is_element(Elem, Set) of - true -> Fset#antidote_set{rems=sets:add_element(Elem,Rems)}; - false -> Fset - end - end. +remove(Elem, #antidote_set{rems=Rems}=Fset) -> + Fset#antidote_set{rems=sets:add_element(Elem,Rems)}. -spec contains(term(), antidote_set()) -> boolean(). -contains(Elem, #antidote_set{set=Set, adds=Adds, rems=Rems}) -> - case sets:is_element(Elem, Adds) of - true -> true; - false -> - case sets:is_element(Elem, Set) of - true -> not sets:is_element(Elem, Rems); - false -> false - end - end. +contains(Elem, #antidote_set{set=Set}) -> + sets:is_element(Elem, Set). %% @doc Determines whether the passed term is a set container. -spec is_type(term()) -> boolean(). is_type(T) -> is_record(T, antidote_set). - %% @doc Returns the symbolic name of this container. --spec type() -> riak_dt_orset. -type() -> riak_dt_orset. +-spec type() -> set. +type() -> set. -to_ops(#antidote_set{key=Key, adds=Adds, rems=Rems}) -> +to_ops(BoundObject, #antidote_set{adds=Adds, rems=Rems}) -> case sets:size(Adds) =:= 0 andalso sets:size(Rems) =:= 0 of - true -> undefined; + true -> []; false -> - AddsAsBin = lists:map(fun(X) -> - erlang:term_to_binary(X) - end,sets:to_list(Adds)), - RemsAsBin = lists:map(fun(X) -> - erlang:term_to_binary(X) - end,sets:to_list(Rems)), - [#fpbsetupdatereq{key=Key, adds=AddsAsBin, rems=RemsAsBin}] + [{BoundObject, add_all, sets:to_list(Adds)}, + {BoundObject, remove_all, sets:to_list(Rems)}] end. -message_for_get(Key) -> #fpbgetsetreq{key=Key}. - %% =================================================================== %% EUnit tests @@ -156,4 +128,3 @@ add_op_existing_set_test() -> [?_assert(ThreeElemSet =:= 3), ?_assert(TwoElemSet =:= 2)]. -endif. - From 2b57dd6912082241686784b5aea9026500bd6f72 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Mon, 21 Sep 2015 14:28:51 +0200 Subject: [PATCH 076/426] remove old interface messages --- src/antidotec_pb_socket.erl | 122 +----------------------------------- 1 file changed, 1 insertion(+), 121 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index d1f35dd56..7c8ccf6e7 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -55,14 +55,7 @@ code_change/3, terminate/2]). --export([ - store_crdt/2, - get_crdt/3, - atomic_store_crdts/2, - atomic_store_crdts/3, - snapshot_get_crdts/2, - snapshot_get_crdts/3, - call_infinity/2 +-export([call_infinity/2 ]). %% @private @@ -233,116 +226,3 @@ cancel_req_timer(undefined) -> cancel_req_timer(Tref) -> _ = erlang:cancel_timer(Tref), ok. - -%%Stores a client-side crdt to the storage by converting the object state to a -%%list of oeprations that will be appended to the log. -%% @todo: propagate only one operation with the list of updates to ensure atomicity. -store_crdt(Obj, Pid) -> - Mod = antidotec_datatype:module_for_term(Obj), - Ops = Mod:to_ops(Obj), - case Ops of - undefined -> ok; - Ops -> - lists:foldl(fun(Op,Success) -> - Result = call_infinity(Pid, {req, Op, ?TIMEOUT}), - case Result of - ok -> Success; - Other -> Other - end - end, ok, Ops) - end. - -%% Reads an object from the storage and returns a client-side -%% representation of the CRDT. -%% @todo Handle different return messages --spec get_crdt(term(), atom(), pid()) -> {ok, term()} | {error, term()}. -get_crdt(Key, Type, Pid) -> - Mod = antidotec_datatype:module_for_type(Type), - Op = Mod:message_for_get(Key), - case call_infinity(Pid, {req, Op, ?TIMEOUT}) of - {ok, Value} -> - {ok, Mod:new(Key,Value)}; - {error, Reason} -> {error, Reason} - end. - -%% Atomically stores multiple CRDTs converting the object state to a -%% list of operations that will be appended to the log. -atomic_store_crdts(Object,Pid) -> - atomic_store_crdts(Object, ignore, Pid). --spec atomic_store_crdts([term()], ignore|term(), pid()) -> {ok, term()} | error | {error, term()}. -atomic_store_crdts(Objects, Clock, Pid) -> - FoldFun = fun(Obj, List) -> - Mod = antidotec_datatype:module_for_term(Obj), - lists:append(List, Mod:to_ops(Obj)) - end, - Operations = lists:foldl(FoldFun, [], Objects), - TxnRequest = case Clock of - ignore -> - #fpbatomicupdatetxnreq{clock=term_to_binary(ignore),ops=encode_au_txn_ops(Operations)}; - _ -> - #fpbatomicupdatetxnreq{clock=Clock,ops=encode_au_txn_ops(Operations)} - end, - Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), - case Result of - {ok, CommitTime} -> {ok, CommitTime}; - error -> error; - {error, Reason} -> {error, Reason}; - Other -> {error, Other} - end. - -%% Read multiple crdts from a consistent snapshot -snapshot_get_crdts(Objects,Pid) -> - snapshot_get_crdts(Objects, ignore, Pid). - --spec snapshot_get_crdts([{term(), atom()}], pid()) -> {ok, term()} | {error, term()}. -snapshot_get_crdts(Objects, Clock, Pid) -> - MapFun = fun({Key,Type}) -> - Mod = antidotec_datatype:module_for_type(Type), - Mod:message_for_get(Key) - end, - Operations = lists:map(MapFun, Objects), - TxnRequest = case Clock of - ignore -> - #fpbsnapshotreadtxnreq{clock=term_to_binary(ignore), ops=encode_snapshot_read_ops(Operations)}; - _ -> - #fpbsnapshotreadtxnreq{clock=Clock, ops=encode_snapshot_read_ops(Operations)} - end, - Result = call_infinity(Pid, {req, TxnRequest, ?TIMEOUT}), - case Result of - {ok, {NewClock, Res}} -> - Zipped = lists:zip(Objects, Res), - ReadObjects = lists:map(fun({{Key,Type},Val}) -> - Mod = antidotec_datatype:module_for_type(Type), - Mod:new(Key,Val) - end, Zipped), - {ok, NewClock, ReadObjects}; - error -> error; - {error, Reason} -> {error, Reason}; - Other -> - {error, Other} - end. - -%% Encode Atomic store crdts request into the -%% pb request message structure to be serialized --spec encode_au_txn_ops([term()]) -> [#fpbatomicupdatetxnop{}]. -encode_au_txn_ops(Operations) -> - lists:map(fun(Op) -> encode_au_txn_op(Op) end, Operations). - -encode_au_txn_op(Op=#fpbincrementreq{}) -> - #fpbatomicupdatetxnop{counterinc=Op}; -encode_au_txn_op(Op=#fpbdecrementreq{}) -> - #fpbatomicupdatetxnop{counterdec=Op}; -encode_au_txn_op(Op=#fpbsetupdatereq{}) -> - #fpbatomicupdatetxnop{setupdate=Op}. - - -%% Encode Snapshot read request into the -%% pb request message record to be serialized --spec encode_snapshot_read_ops([term()]) -> [#fpbsnapshotreadtxnop{}]. -encode_snapshot_read_ops(Operations) -> - lists:map(fun(Op) -> encode_snapshot_read_op(Op) end, Operations). - -encode_snapshot_read_op(Op=#fpbgetcounterreq{}) -> - #fpbsnapshotreadtxnop{counter=Op}; -encode_snapshot_read_op(Op=#fpbgetsetreq{}) -> - #fpbsnapshotreadtxnop{set=Op}. From ff6c342dd1369d58b6b3e141fa96a03993060329 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 11:43:57 +0200 Subject: [PATCH 077/426] added is_operation method for type checking --- src/crdt_rga.erl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index fea00ac63..836e94f87 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -17,7 +17,7 @@ %% @end -module(crdt_rga). --export([new/0, update/2, purge_tombstones/1, generate_downstream/3, value/1]). +-export([new/0, update/2, purge_tombstones/1, generate_downstream/3, value/1, is_operation/1]). -export_type([rga/0, rga_op/0, rga_downstream_op/0]). @@ -120,6 +120,18 @@ purge_tombstones(Rga) -> unique() -> crypto:strong_rand_bytes(20). +%% @doc The following operation verifies that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(Operation) -> + case Operation of + {addRight, _, Position} -> + (is_integer(Position) and (Position >= 0)); + {remove, Position} -> + (is_integer(Position) and (Position >= 0)); + _ -> + false + end. + -ifdef(TEST). From a09184bf902ec17927ad66a00189b92b4c0532e7 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 11:49:25 +0200 Subject: [PATCH 078/426] added is_operation method test --- src/crdt_rga.erl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 836e94f87..5b6cc164e 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -21,9 +21,9 @@ -export_type([rga/0, rga_op/0, rga_downstream_op/0]). --ifdef(TEST). +%% -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). --endif. +%% -endif. -type vertex() :: {atom(), any(), number()}. @@ -267,6 +267,21 @@ concurrent_updates_in_two_replicas_test() -> {ok, R2_4} = update(DownstreamOp3, R2_3), ?assertEqual(R1_4, R2_4). +is_operation_test() -> + %% addRight checks + ?assertEqual(false, is_operation({addRight, value, -1})), + ?assertEqual(true, is_operation({addRight, value, 0})), + ?assertEqual(true, is_operation({addRight, value, 1})), + + %% remove checks + ?assertEqual(false, is_operation({remove, -1})), + ?assertEqual(true, is_operation({remove, 0})), + ?assertEqual(true, is_operation({remove, 1})), + + %% invalid operation checks + ?assertEqual(false, is_operation({anything, 1})), + ?assertEqual(false, is_operation({add, 1, 4})). + -endif. From 8433560a1b15a89062032ecc8216bc04dc62de9b Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 12:00:36 +0200 Subject: [PATCH 079/426] remove commented include eunit --- src/crdt_rga.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 5b6cc164e..0dab86e73 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -21,9 +21,9 @@ -export_type([rga/0, rga_op/0, rga_downstream_op/0]). -%% -ifdef(TEST). +-ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -%% -endif. +-endif. -type vertex() :: {atom(), any(), number()}. From 62d720b59691a704d2b73477e0848e0436ad7cc5 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 12:59:21 +0200 Subject: [PATCH 080/426] added the copyright notice to crdt_rga module --- src/crdt_rga.erl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 0dab86e73..f2336b5a9 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -1,3 +1,23 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2015 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + %% @doc %% %% An operation-based Replicated Growable Array CRDT. From 43546c15fe52f54793eeedb4338e2e642d42e210 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 13:06:50 +0200 Subject: [PATCH 081/426] purge_tombstones method now uses lists:filter --- src/crdt_rga.erl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index f2336b5a9..5b9ea6b43 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -128,13 +128,10 @@ recursive_remove(Vertex, [H | T], L) -> %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. -spec purge_tombstones(rga()) -> rga_result(). purge_tombstones(Rga) -> - L = lists:foldl(fun({Status, Value, UID}, L) -> - case Status == deleted of - true -> L; - _ -> [{Status, Value, UID} | L] - end - end, [], Rga), - {ok, lists:reverse(L)}. + L = lists:filter(fun({Status, _, _}) -> + Status == ok + end, Rga), + {ok, L}. %% @doc generate a unique identifier (best-effort). unique() -> From 14e352de515509ac62983c148ef348797854c5b2 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 14:22:14 +0200 Subject: [PATCH 082/426] removed trailing lines --- src/crdt_rga.erl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 5b9ea6b43..a25504e51 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -300,6 +300,3 @@ is_operation_test() -> ?assertEqual(false, is_operation({add, 1, 4})). -endif. - - - From 3455baf4ae1cf3aa984716be242c98489539f405 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 14:53:56 +0200 Subject: [PATCH 083/426] refactored recursive_remove to use lists:keyreplace --- src/crdt_rga.erl | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index a25504e51..8fbdc4e0d 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -87,7 +87,7 @@ value(Rga) -> update({addRight, RightVertex, NewVertex}, Rga) -> recursive_insert(RightVertex, NewVertex, Rga, []); update({remove, Vertex}, Rga) -> - recursive_remove(Vertex, Rga, []). + recursive_remove(Vertex, Rga). %% Private %% @doc recursively looks for the Vertex where the new element should be put to the right of. @@ -115,15 +115,11 @@ add_element(Insert, [], L) -> {ok, lists:reverse([Insert | L])}. %% Private -%% @doc recursively looks for the Vertex to be removed. Once it's found, it's marked as "deleted". +%% @doc looks for the Vertex to be removed. Once it's found, it's marked as "deleted". %% The Vertex is not removed from the list, to allow adding elements to its right. --spec recursive_remove(vertex(), rga(), list()) -> rga_result(). -recursive_remove(_, [], L) -> - {ok, L}; -recursive_remove({_, Value, UID}, [{_, Value, UID} | T], L) -> - {ok, lists:reverse(L) ++ [{deleted, Value, UID}] ++ T}; -recursive_remove(Vertex, [H | T], L) -> - recursive_remove(Vertex, T, [H | L]). +-spec recursive_remove(vertex(), rga()) -> rga_result(). +recursive_remove({ok, Value, UID}, Rga) -> + {ok, lists:keyreplace(UID, 3, Rga, {deleted, Value, UID})}. %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. -spec purge_tombstones(rga()) -> rga_result(). From 3b5182f6e26b3390630b8bf9f0c41b48538b61d6 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 15:06:45 +0200 Subject: [PATCH 084/426] refactored recursive_remove to remove_vertex --- src/crdt_rga.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 8fbdc4e0d..e7d5e256a 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -87,7 +87,7 @@ value(Rga) -> update({addRight, RightVertex, NewVertex}, Rga) -> recursive_insert(RightVertex, NewVertex, Rga, []); update({remove, Vertex}, Rga) -> - recursive_remove(Vertex, Rga). + remove_vertex(Vertex, Rga). %% Private %% @doc recursively looks for the Vertex where the new element should be put to the right of. @@ -117,8 +117,8 @@ add_element(Insert, [], L) -> %% Private %% @doc looks for the Vertex to be removed. Once it's found, it's marked as "deleted". %% The Vertex is not removed from the list, to allow adding elements to its right. --spec recursive_remove(vertex(), rga()) -> rga_result(). -recursive_remove({ok, Value, UID}, Rga) -> +-spec remove_vertex(vertex(), rga()) -> rga_result(). +remove_vertex({ok, Value, UID}, Rga) -> {ok, lists:keyreplace(UID, 3, Rga, {deleted, Value, UID})}. %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. From 539fdc4ef4bb51db582e8bce191eeff836fa17af Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Wed, 23 Sep 2015 17:47:40 +0200 Subject: [PATCH 085/426] dialyzer fixes --- src/crdt_rga.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index e7d5e256a..19d2f7738 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -45,15 +45,15 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --type vertex() :: {atom(), any(), number()}. +-type vertex() :: {ok | deleted, any(), number()}. --type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, vertex()}. +-type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, {ok, any(), number()}}. --type rga_op() :: {addRight, any(), number()} | {remove, number()}. +-type rga_op() :: {addRight, any(), non_neg_integer()} | {remove, non_neg_integer()}. -type rga_result() :: {ok, rga()}. --type rga() :: list(). +-type rga() :: [vertex()]. -type actor() :: riak_dt:actor(). From c17139f338f92dc54507e3453c96e97edd22400f Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Fri, 25 Sep 2015 17:08:39 +0200 Subject: [PATCH 086/426] new way of creating UIDs based on the node and a call make_ref() --- src/crdt_rga.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 19d2f7738..73f120adc 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -129,9 +129,9 @@ purge_tombstones(Rga) -> end, Rga), {ok, L}. -%% @doc generate a unique identifier (best-effort). +%% @doc generates a unique identifier based on the node and a unique reference. unique() -> - crypto:strong_rand_bytes(20). + {node(), make_ref()}. %% @doc The following operation verifies that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). From 1116564e0d1d11a5f7f44cdea5949585c38f2e53 Mon Sep 17 00:00:00 2001 From: santialvarezcolombo Date: Tue, 29 Sep 2015 11:03:34 +0200 Subject: [PATCH 087/426] fix bug when position 0 is used --- src/crdt_rga.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index 73f120adc..ed06ef2b2 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -68,9 +68,9 @@ new() -> generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> case (Position < 0) or (Position > length(Rga)) of true -> {error, {invalid_position, Position}}; - false -> case length(Rga) of - 0 -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; - _ -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} + false -> case (length(Rga) == 0) or (Position == 0) of + true -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; + false -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} end end; generate_downstream({remove, Position}, _Actor, Rga) -> From f533f47fb64f5b50e0f303b8cccd8dbb3b61e534 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 1 Oct 2015 10:52:30 +0200 Subject: [PATCH 088/426] support static transactions at client side --- src/antidotec_pb.erl | 87 +++++++++++++++++++++++++++++-------- src/antidotec_pb_socket.erl | 19 +++++++- 2 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index 9f4d69e78..a359bdd22 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -33,24 +33,28 @@ -spec start_transaction(Pid::term(), TimeStamp::term(), TxnProperties::term()) -> {ok, term()} | {error, term()}. start_transaction(Pid, TimeStamp, TxnProperties) -> - EncMsg = antidote_pb_codec:encode(start_transaction, - {TimeStamp, TxnProperties}), - Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), - case Result of - {error, timeout} -> {error, timeout}; - _ -> - case antidote_pb_codec:decode_response(Result) of - {start_transaction, TxId} -> - {ok, TxId}; - {error, Reason} -> - {error, Reason}; - Other -> - {error, Other} + case is_static(TxnProperties) of + true -> {ok, {static, {TimeStamp, TxnProperties}}}; + false -> + EncMsg = antidote_pb_codec:encode(start_transaction, + {TimeStamp, TxnProperties}), + Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {start_transaction, TxId} -> + {ok, {interactive, TxId}}; + {error, Reason} -> + {error, Reason}; + Other -> + {error, Other} + end end end. -spec abort_transaction(Pid::term(), TxId::term()) -> ok. -abort_transaction(Pid, TxId) -> +abort_transaction(Pid, {interactive, TxId}) -> EncMsg = antidote_pb_codec:encode(abort_transaction, TxId), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), case Result of @@ -65,7 +69,7 @@ abort_transaction(Pid, TxId) -> -spec commit_transaction(Pid::term(), TxId::term()) -> {ok, term()} | {error, term()}. -commit_transaction(Pid, TxId) -> +commit_transaction(Pid, {interactive, TxId}) -> EncMsg = antidote_pb_codec:encode(commit_transaction, TxId), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), case Result of @@ -76,10 +80,15 @@ commit_transaction(Pid, TxId) -> {error, Reason} -> {error, Reason}; Other -> {error, Other} end + end; +commit_transaction(Pid, {static, _TxId}) -> + case antidotec_pb_socket:get_last_commit_time(Pid) of + {ok, CommitTime} -> + {ok, CommitTime} end. %%-spec update_objects(Pid::term(), Updates::[{bound_object(), op(), op_parm()}], TxId::term()) -> ok | {error, term()}. -update_objects(Pid, Updates, TxId) -> +update_objects(Pid, Updates, {interactive, TxId}) -> EncMsg = antidote_pb_codec: encode(update_objects, {Updates, TxId}), Result = antidotec_pb_socket: call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), case Result of @@ -90,9 +99,26 @@ update_objects(Pid, Updates, TxId) -> {error, Reason} -> {error, Reason}; Other -> {error, Other} end + end; + +update_objects(Pid, Updates, {static, TxId}) -> + {Clock, Properties} = TxId, + EncMsg = antidote_pb_codec:encode(static_update_objects, + {Clock, Properties, Updates}), + Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {commit_transaction, CommitTimeStamp} -> + antidotec_pb_socket:store_commit_time(Pid, CommitTimeStamp), + ok; + {error, Reason} -> {error, Reason} + end end. + -read_objects(Pid, Objects, TxId) -> +read_objects(Pid, Objects, {interactive, TxId}) -> EncMsg = antidote_pb_codec:encode(read_objects, {Objects, TxId}), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), case Result of @@ -108,4 +134,31 @@ read_objects(Pid, Objects, TxId) -> {error, Reason} -> {error, Reason}; Other -> {error, Other} end + end; +read_objects(Pid, Objects, {static, TxId}) -> + {Clock, Properties} = TxId, + EncMsg = antidote_pb_codec:encode(static_read_objects, + {Clock, Properties, Objects}), + Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {static_read_objects_resp, Values, CommitTimeStamp} -> + antidotec_pb_socket:store_commit_time(Pid, CommitTimeStamp), + ResObjects = lists:map( + fun({Type, Val}) -> + Mod = antidotec_datatype:module_for_type(Type), + Mod:new(Val) + end, Values), + {ok, ResObjects}; + {error, Reason} -> {error, Reason} + end + end. + +is_static(TxnProperties) -> + case TxnProperties of + [{static, true}] -> + true; + _ -> false end. diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 7c8ccf6e7..13a155391 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -42,7 +42,8 @@ sock :: port(), % gen_tcp socket active :: #request{} | undefined, % active request connect_timeout=infinity :: timeout(), % timeout of TCP connection - keepalive = false :: boolean() % if true, enabled TCP keepalive for the socket + keepalive = false :: boolean(), % if true, enabled TCP keepalive for the socket + last_commit_time :: term() % temporarily store for static transactions }). -export([start_link/2, start_link/3, @@ -55,7 +56,9 @@ code_change/3, terminate/2]). --export([call_infinity/2 +-export([call_infinity/2, + store_commit_time/2, + get_last_commit_time/1 ]). %% @private @@ -96,10 +99,22 @@ stop(Pid) -> call_infinity(Pid, Msg) -> gen_server:call(Pid, Msg, infinity). +store_commit_time(Pid, TimeStamp) -> + gen_server:call(Pid, {store_commit_time, TimeStamp}, infinity). + +get_last_commit_time(Pid) -> + gen_server:call(Pid, get_commit_time, infinity). + %% @private handle_call({req, Msg, Timeout}, From, State) -> {noreply, send_request(new_request(Msg, From, Timeout), State)}; +handle_call({store_commit_time, TimeStamp}, _From, State) -> + {reply, ok, State#state{last_commit_time = TimeStamp}}; + +handle_call(get_commit_time, _From, State=#state{last_commit_time = TimeStamp}) -> + {reply, {ok, TimeStamp}, State#state{last_commit_time = ignore}}; + handle_call(stop, _From, State) -> _ = disconnect(State), {stop, normal, ok, State}. From 41da530db53666cb40ab7c061d5a857db3751f4e Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Wed, 7 Oct 2015 10:52:29 +0200 Subject: [PATCH 089/426] Fixing small things - Use of list length - Indentation --- src/crdt_rga.erl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl index ed06ef2b2..5656675cb 100644 --- a/src/crdt_rga.erl +++ b/src/crdt_rga.erl @@ -68,7 +68,7 @@ new() -> generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> case (Position < 0) or (Position > length(Rga)) of true -> {error, {invalid_position, Position}}; - false -> case (length(Rga) == 0) or (Position == 0) of + false -> case (Rga == []) or (Position == 0) of true -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; false -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} end @@ -124,9 +124,7 @@ remove_vertex({ok, Value, UID}, Rga) -> %% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. -spec purge_tombstones(rga()) -> rga_result(). purge_tombstones(Rga) -> - L = lists:filter(fun({Status, _, _}) -> - Status == ok - end, Rga), + L = lists:filter(fun({Status, _, _}) -> Status == ok end, Rga), {ok, L}. %% @doc generates a unique identifier based on the node and a unique reference. From 2b7e97cee3dfa6e016a8c809b0ffaacf67c107e5 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 15 Dec 2015 04:04:54 +0000 Subject: [PATCH 090/426] Add antidote reigster --- src/antidotec_datatype.erl | 9 +++-- src/antidotec_reg.erl | 82 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 src/antidotec_reg.erl diff --git a/src/antidotec_datatype.erl b/src/antidotec_datatype.erl index c469bd903..c8412b169 100644 --- a/src/antidotec_datatype.erl +++ b/src/antidotec_datatype.erl @@ -27,7 +27,7 @@ -endif. --define(MODULES, [antidotec_counter, antidotec_set]). +-define(MODULES, [antidotec_counter, antidotec_set, antidotec_reg]). -export([module_for_type/1, module_for_term/1]). @@ -63,10 +63,11 @@ -callback type() -> typename(). %% @doc Returns the module name for the container of the given CRDT data-type. --spec module_for_type(set | counter) -> - antidotec_counter | antidotec_set. +-spec module_for_type(set | counter | reg) -> + antidotec_counter | antidotec_set | antidotec_reg. module_for_type(set) -> antidotec_set; -module_for_type(counter) -> antidotec_counter. +module_for_type(counter) -> antidotec_counter, +module_for_type(reg) -> antidotec_reg. %% @doc Returns the container module name for the given term. %% Returns undefined if the module is not known. diff --git a/src/antidotec_reg.erl b/src/antidotec_reg.erl new file mode 100644 index 000000000..b7eed8dee --- /dev/null +++ b/src/antidotec_reg.erl @@ -0,0 +1,82 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- +-module(antidotec_reg). + +-include_lib("riak_pb/include/antidote_pb.hrl"). + +-behaviour(antidotec_datatype). + +-export([new/0, + new/1, + value/1, + is_type/1, + to_ops/2, + type/0 + ]). + +-export([assign/2 + ]). + +-record(antidote_reg, { + value + }). + +-export_type([antidote_reg/0]). +-opaque antidote_reg() :: #antidote_reg{}. + +-ifdef(TEST). +-compile(export_all). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + +-spec new() -> antidote_reg(). +new() -> + #antidote_reg{value=""}. + + +new(Value) -> + #antidote_reg{value=Value}. + +-spec value(antidote_reg()) -> [term()]. +value(#antidote_reg{value=Value}) -> Value. + + +%% @doc Determines whether the passed term is a reg container. +-spec is_type(term()) -> boolean(). +is_type(T) -> + is_record(T, antidote_reg). + +%% @doc Returns the symbolic name of this container. +-spec type() -> reg. +type() -> reg. + +to_ops(_, _) -> + ok. + +assign(_, Value) -> + #antidote_reg{value=Value}. + + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). +-endif. From bf31ffba5908336e36d61f01fb1607fff0d69ea6 Mon Sep 17 00:00:00 2001 From: Zhongmiao Li Date: Tue, 15 Dec 2015 04:06:40 +0000 Subject: [PATCH 091/426] Fix bug --- src/antidotec_datatype.erl | 2 +- src/antidotec_reg.erl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/antidotec_datatype.erl b/src/antidotec_datatype.erl index c8412b169..91976607c 100644 --- a/src/antidotec_datatype.erl +++ b/src/antidotec_datatype.erl @@ -66,7 +66,7 @@ -spec module_for_type(set | counter | reg) -> antidotec_counter | antidotec_set | antidotec_reg. module_for_type(set) -> antidotec_set; -module_for_type(counter) -> antidotec_counter, +module_for_type(counter) -> antidotec_counter; module_for_type(reg) -> antidotec_reg. %% @doc Returns the container module name for the given term. diff --git a/src/antidotec_reg.erl b/src/antidotec_reg.erl index b7eed8dee..32290ad7e 100644 --- a/src/antidotec_reg.erl +++ b/src/antidotec_reg.erl @@ -26,6 +26,7 @@ -export([new/0, new/1, value/1, + dirty_value/1, is_type/1, to_ops/2, type/0 @@ -58,6 +59,7 @@ new(Value) -> -spec value(antidote_reg()) -> [term()]. value(#antidote_reg{value=Value}) -> Value. +dirty_value(#antidote_reg{value=Value}) -> Value. %% @doc Determines whether the passed term is a reg container. -spec is_type(term()) -> boolean(). From 5adb206c131538845abe080e6b8719bb4a14dc46 Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Thu, 17 Dec 2015 21:36:17 +0100 Subject: [PATCH 092/426] added missing tools.mk --- tools.mk | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tools.mk diff --git a/tools.mk b/tools.mk new file mode 100644 index 000000000..66c6a16c5 --- /dev/null +++ b/tools.mk @@ -0,0 +1,57 @@ +REBAR ?= ./rebar + +test: compile + ${REBAR} eunit skip_deps=true + +docs: + ${REBAR} doc skip_deps=true + +xref: compile + ${REBAR} xref skip_deps=true + +PLT ?= $(HOME)/.combo_dialyzer_plt +LOCAL_PLT = .local_dialyzer_plt +DIALYZER_FLAGS ?= -Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspecs + +${PLT}: compile + @if [ -f $(PLT) ]; then \ + dialyzer --check_plt --plt $(PLT) --apps $(DIALYZER_APPS) && \ + dialyzer --add_to_plt --plt $(PLT) --output_plt $(PLT) --apps $(DIALYZER_APPS) ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(PLT) --apps $(DIALYZER_APPS); test $$? -ne 1; \ + fi + +${LOCAL_PLT}: compile + @if [ -d deps ]; then \ + if [ -f $(LOCAL_PLT) ]; then \ + dialyzer --check_plt --plt $(LOCAL_PLT) deps/*/ebin && \ + dialyzer --add_to_plt --plt $(LOCAL_PLT) --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + fi \ + fi + +dialyzer: ${PLT} ${LOCAL_PLT} + @echo "==> $(shell basename $(shell pwd)) (dialyzer)" + @if [ -f $(LOCAL_PLT) ]; then \ + PLTS="$(PLT) $(LOCAL_PLT)"; \ + else \ + PLTS=$(PLT); \ + fi; \ + if [ -f dialyzer.ignore-warnings ]; then \ + if [ $$(grep -cvE '[^[:space:]]' dialyzer.ignore-warnings) -ne 0 ]; then \ + echo "ERROR: dialyzer.ignore-warnings contains a blank/empty line, this will match all messages!"; \ + exit 1; \ + fi; \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin > dialyzer_warnings ; \ + egrep -v "^[[:space:]]*(done|Checking|Proceeding|Compiling)" dialyzer_warnings | grep -F -f dialyzer.ignore-warnings -v > dialyzer_unhandled_warnings ; \ + cat dialyzer_unhandled_warnings ; \ + [ $$(cat dialyzer_unhandled_warnings | wc -l) -eq 0 ] ; \ + else \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin; \ + fi + +cleanplt: + rm -f $(PLT) + rm -f $(LOCAL_PLT) + From 1b83d8c3aadd0d0f3039a392c0d629297d54de41 Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Thu, 17 Dec 2015 22:33:44 +0100 Subject: [PATCH 093/426] Dialyzer fixes --- src/antidotec_pb.erl | 10 ++++++---- src/antidotec_pb_socket.erl | 20 +++++++++++--------- src/antidotec_reg.erl | 3 ++- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index a359bdd22..be13a5f4b 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -31,16 +31,18 @@ -define(TIMEOUT, 10000). -spec start_transaction(Pid::term(), TimeStamp::term(), TxnProperties::term()) - -> {ok, term()} | {error, term()}. + -> {ok,{interactive,term()} | {static,{term(),term()}}} | {error, term()}. start_transaction(Pid, TimeStamp, TxnProperties) -> case is_static(TxnProperties) of - true -> {ok, {static, {TimeStamp, TxnProperties}}}; + true -> + {ok, {static, {TimeStamp, TxnProperties}}}; false -> EncMsg = antidote_pb_codec:encode(start_transaction, {TimeStamp, TxnProperties}), Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), case Result of - {error, timeout} -> {error, timeout}; + {error, timeout} -> + {error, timeout}; _ -> case antidote_pb_codec:decode_response(Result) of {start_transaction, TxId} -> @@ -67,7 +69,7 @@ abort_transaction(Pid, {interactive, TxId}) -> end end. --spec commit_transaction(Pid::term(), TxId::term()) -> +-spec commit_transaction(Pid::term(), TxId::{interactive,term()} | {static,term()}) -> {ok, term()} | {error, term()}. commit_transaction(Pid, {interactive, TxId}) -> EncMsg = antidote_pb_codec:encode(commit_transaction, TxId), diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 13a155391..d75efb507 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -39,15 +39,18 @@ -record(state, { address :: address(), % address to connect to port :: portnum(), % port to connect to - sock :: port(), % gen_tcp socket + sock :: port() | undefined, % gen_tcp socket active :: #request{} | undefined, % active request - connect_timeout=infinity :: timeout(), % timeout of TCP connection + connect_timeout = infinity :: timeout(), % timeout of TCP connection keepalive = false :: boolean(), % if true, enabled TCP keepalive for the socket last_commit_time :: term() % temporarily store for static transactions }). --export([start_link/2, start_link/3, - start/2, start/3, + +-export([start_link/2, + start_link/3, + start/2, + start/3, stop/1, handle_call/3, handle_info/2, @@ -67,7 +70,8 @@ init([Address, Port, _Options]) -> case connect(State) of {error, Reason} -> {stop, {tcp, Reason}}; - Ok -> Ok + {ok, State} -> + {ok, State} end. %% @doc Create a linked process to talk with the riak server on Address:Port @@ -162,7 +166,8 @@ connect(State) when State#state.sock =:= undefined -> State#state.connect_timeout) of {ok, Sock} -> {ok, State#state{sock = Sock}}; - Error -> Error + {error, Reason} -> + {error, Reason} end. @@ -210,9 +215,6 @@ send_request(Request0, State) when State#state.active =:= undefined -> maybe_reply({noreply,State#state{active = Request}}); {error, Reason} -> lager:warning("Socket error while sending riakc request: ~p.", [Reason]), - gen_tcp:close(State#state.sock); - Other -> - lager:warning("Socket error while sending riakc request: ~p.", [Other]), gen_tcp:close(State#state.sock) end. diff --git a/src/antidotec_reg.erl b/src/antidotec_reg.erl index 32290ad7e..eb5bfbb0d 100644 --- a/src/antidotec_reg.erl +++ b/src/antidotec_reg.erl @@ -70,8 +70,9 @@ is_type(T) -> -spec type() -> reg. type() -> reg. +-spec to_ops(term(),term()) -> []. to_ops(_, _) -> - ok. + []. assign(_, Value) -> #antidote_reg{value=Value}. From 8030c14f3078e7db7ad71ef4824d6f6ff594efb5 Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Fri, 18 Dec 2015 00:09:07 +0100 Subject: [PATCH 094/426] try to fix --- src/antidotec_pb_socket.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index d75efb507..6bc2376db 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -39,7 +39,7 @@ -record(state, { address :: address(), % address to connect to port :: portnum(), % port to connect to - sock :: port() | undefined, % gen_tcp socket + sock :: port(), % gen_tcp socket active :: #request{} | undefined, % active request connect_timeout = infinity :: timeout(), % timeout of TCP connection keepalive = false :: boolean(), % if true, enabled TCP keepalive for the socket @@ -70,8 +70,8 @@ init([Address, Port, _Options]) -> case connect(State) of {error, Reason} -> {stop, {tcp, Reason}}; - {ok, State} -> - {ok, State} + {ok, State2} -> + {ok, State2} end. %% @doc Create a linked process to talk with the riak server on Address:Port From 19cc7c210a4b8c44364cf194584b7d54e3c582b6 Mon Sep 17 00:00:00 2001 From: Tyler Crain Date: Fri, 18 Dec 2015 00:26:41 +0100 Subject: [PATCH 095/426] fix match crash --- src/antidotec_pb_socket.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index d75efb507..72f9d718c 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -71,7 +71,9 @@ init([Address, Port, _Options]) -> {error, Reason} -> {stop, {tcp, Reason}}; {ok, State} -> - {ok, State} + {ok, State}; + Other -> + Other end. %% @doc Create a linked process to talk with the riak server on Address:Port From d761dac24fc5d7c6734f10307a0e3f7a843541e1 Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Fri, 18 Dec 2015 00:34:36 +0100 Subject: [PATCH 096/426] Try sock fix --- src/antidotec_pb_socket.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/antidotec_pb_socket.erl b/src/antidotec_pb_socket.erl index 6bc2376db..ebbab0ba9 100644 --- a/src/antidotec_pb_socket.erl +++ b/src/antidotec_pb_socket.erl @@ -39,7 +39,7 @@ -record(state, { address :: address(), % address to connect to port :: portnum(), % port to connect to - sock :: port(), % gen_tcp socket + sock :: port() | undefined, % gen_tcp socket active :: #request{} | undefined, % active request connect_timeout = infinity :: timeout(), % timeout of TCP connection keepalive = false :: boolean(), % if true, enabled TCP keepalive for the socket @@ -66,7 +66,7 @@ %% @private init([Address, Port, _Options]) -> - State = #state{address = Address, port = Port, active = undefined}, + State = #state{address = Address, port = Port, active = undefined, sock = undefined}, case connect(State) of {error, Reason} -> {stop, {tcp, Reason}}; From e53af25a086b79469b43b5ede907f5c10095e699 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Wed, 6 Jan 2016 11:08:53 +0100 Subject: [PATCH 097/426] udpate readme --- README.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f6c308be5..af509b130 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,58 @@ -antidote_pb -========= +#antidote_pb -Erlang client for antiodote protocol buffer interface \ No newline at end of file +Erlang client for antiodote protocol buffer interface + +###Interface for transactions + +* start\_transaction (Pid, timestamp, properties) --> transaction\_descriptor + + starts a new transaction and returns a transaction_descriptor which is a transaction identifier to be used with further operations of the transaction. timestamp provides the causality information. properties is a list of configurable parameters for the transaction. Currently only property supported which specifies to use static or interactive transactions. +Example: + + Clock = term_to_binary(ignore), %% First time there is no clock information + {ok, TxId} = start_transaction(Pid, Clock, [{static=true}]). %% Use static transactions + +* read\_objects (Pid, [bound\_object], transaction\_descriptor) --> {ok, Vals} + + reads a set of keys. + Example: + + {ok, [Val1, Val2]} = ([O1, O2], TxId), + Value = antidotec_counter:value(Val1). %% Assuming O1 is of type counter + +* update\_objects (Pid, [{bound\_object, operation, op_parameters}], transaction\_descriptor) -> ok + + update a set of object with the specified operations. operation is any allowed (upstream) operation on the crdt type for bound\_object, op\_parameters are parameters to the operation. + Example: + + Obj = antidotec_counter:increment(1, antidotec_counter:new()), + ok = antidotec_pb:update_objects(Pid, + antidotec_counter:to_ops(BObj, Obj), + TxId). + +* abort\_transaction (Pid, transaction_descriptor) + aborts a transaction + +* commit\_transaction (Pid, transaction_descriptor) --> {ok,timestamp} OR aborted + + +Example +====== + + %% Starts pb socket + {ok, Pid} = antidotec_pb_socket:start(?ADDRESS, ?PORT), + + BObj = {Key, riak_dt_pncounter, Bucket}, + Obj = antidotec_counter:increment(Amount, antidotec_counter:new()), + {ok, TxId} = antidotec_pb:start_transaction(Pid, term_to_binary(ignore), {}), + ok = antidotec_pb:update_objects(Pid, + antidotec_counter:to_ops(BObj, Obj), + TxId), + {ok, TimeStamp} = antidotec_pb:commit_transaction(Pid, TxId), + %% Use TimeStamp for subsequent transactions if required + {ok, TxId2} = antidotec_pb:start_transaction(Pid, TimeStamp, [{static=true}]), + ... + ... + + %% Close pb socket + _Disconnected = antidotec_pb_socket:stop(Pid), From 9ff104add03045663f2013c3164a2c3e1b60d32c Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 10 May 2016 10:16:47 +0200 Subject: [PATCH 098/426] add antidote_crdt base files --- include/antidote_crdt.hrl | 23 +++++ rebar | Bin 0 -> 201543 bytes src/antidote_crdt.app.src | 14 +++ src/antidote_crdt.erl | 44 ++++++++ src/antidote_crdt_counter.erl | 189 ++++++++++++++++++++++++++++++++++ 5 files changed, 270 insertions(+) create mode 100644 include/antidote_crdt.hrl create mode 100755 rebar create mode 100644 src/antidote_crdt.app.src create mode 100644 src/antidote_crdt.erl create mode 100644 src/antidote_crdt_counter.erl diff --git a/include/antidote_crdt.hrl b/include/antidote_crdt.hrl new file mode 100644 index 000000000..15ffe5ad3 --- /dev/null +++ b/include/antidote_crdt.hrl @@ -0,0 +1,23 @@ +-type crdt() :: term(). +-type update() :: term(). +-type effect() :: term(). +-type value() :: term(). +-type reason() :: term(). + +-type pncounter() :: integer(). +-type pncounter_update() :: increment | decrement | + {increment, integer()} | + {decrement, integer()}. +-type pncounter_effect() :: pncounter_update(). +-type pncounter_value() :: integer(). + + +-export_type([ crdt/0, + update/0, + effect/0, + value/0, + pncounter/0, + pncounter_update/0, + pncounter_effect/0, + pncounter_value/0 + ]). diff --git a/rebar b/rebar new file mode 100755 index 0000000000000000000000000000000000000000..a543d531d5fa8bb9f6b0eecc21e11aa8039c568a GIT binary patch literal 201543 zcmZ_#bBr%M^ev2!?KxxHI%C_mZQHhO+qP}nJY(CR!TWsg{UJBGZ_~6*y0UlwXtP(l zx=Dx_T%Da5j4bUKOzqqVO`VOMEFD~6$jJVyM1*t>hJ;S0Mutud|GPE)4+o2oscQ5H%uQj$bX4z+Wh;A#SmuZ_@n6Y_;)UAxyKEPb zXJqp!T*8h0vynLC?28oIK01kdPFiRU$<<4<_g18+;73?!>jY^h-{jxd7T0Lt`Vg7x zNf)UDSIM64Uh-SApYyL9gOGrHnYI;7D$Ez5YR<+5CGPwL03GCb4P)^8p?ngNs|pHwmc$rg7Fms7nPG zrp(#OYJ@BOIaE<8f*7F;h-!sWwOkEjF1SoHg!WUm=Lpe25wdP-w*LlGpmmr<4Q_Wa z)TRT&xPq`);bj5Xp$bOqS`blpBTW)^CkXh~l^-p13p>?v)l@)5Y@6RmPvZm9nZeeA z>n*J@&2rp9ULv54(7G|sia?*Q%m-meC>cfw`2b&#SO-Ikp0=qvd`}|kRF08Gn)5M@ zdag(7d@2i{$COvxgXVsVaB>S0qcXlc{GxFE*svlVU2RCzJzyLq)6_fFW8>A&{2z2p z5H9ms=O0@=<@D0Ktfd*v)Gk-qSf20Q`ADZSBy}#Ts?$2TP(rKQOdv| z^$4I)pDkt!o}8S6Z(F8%N-b(G4?Zn}pg!8yjJbvB=d- zfTRG-X=80dX`yJ_Av1L4S5_o)T414#ro|ApLLw^3l8~*F5TC_$El`CQzHFhIgIV9jHax_t-_e5JTS$ z5^y8ylPm{cpOM&c_4%dK)a;`cPGInf;KBkf@8o0X=?6pmTAj1ksn#(*;rMySAv41?gklj>A>%)+PfD(Hm6Qsh^T?A=0$ z^6J5xO85yq(8HUQAv(vp0VV$l3>-MgK!qAysCSUYK(Wrnb=^lWlS;QrWxPadPXXu2 zLBa?No0OhbLApzg#Cd`!c*s((&GU2+jm|$6h+|c|c8srUQow}ed8olk$=4xVC)-HS z@(nmAB99)#hOj7~T1QWwG0~=*cQxWd3j^Ilfd$=?aiVQq7FjD`oY)MRWd!2jjn+dUe)hXq zmQk>MTMbj-r;OaAST21fZuN1|cP-9$M_NbdjYjWsM)zjupM3^E~YeLo^WL*C;Fv5DG>Q9bA6$y`17Y&XqKUlf$ z)YHaD?wJ~Cp~{jc$|5IgDlX9Yf!d?I1Z513WpxmvHVa#ZqR->fUmHwo4C-tUr9ihu z?I373){^)d`V7k-?%s{Ee@AjEZzw9NG3}aOWZ*MkxOGhF47R4l8T6Dl7~5`c?Z#_! zxs3yE@Z!&U4C5}$nxansn1<_(zqB}5+HjUhODQ5;dD>AGP?|4PB5C$I0q5=oGzXrg zMth;M*F{L1ix*{1Y0{o!he1Zv5MHWYx8Hm5JXY-xlhe%WG`MFRx#(ayFD@zmI}nu$ ziByHsH$BX>Rxt||Beo!yL}skC@vMo*(e0EV;Qg~iLcU3Pj=6*?EfRpXg!-@5p?Bla zBzGV|4@qGbF7!Fb3}!xIPgDmYEnzUL!LNo`)J0{Oet1B=y7E{9(^FewSlA24qd%2- z89Z}Yw5Cj+dp(`V*CV-3iNF{g&rguWY@jH9a4V{Tbg-;Ga9?ri#aKfBb8WtWdnUo} z9s*y~nEyNru8bLdZUmdz@V{yE2xw4)g&NOu`vyG&3I9}&EG$yg9ren98Hk^v&}oqx z;wnvupR9=t(IWu|wgH3QQY(0tbAc|$h*MM$qu$U_^C94q;h0oKz2-lEp?XY=Er8r| zt++AUB%cS9O%^Q{bt25*-~;`oP;@!hjx1Ku^J7P8MnHrE`Ba7tb)C;dPVp-ebY@IN zGaxOwl@_Wi8$hLmEvYe|?%g(Gd=w@agHyxyVeBhe#5JhnTAhRq_%(<;S5i}ngllqU zb!<*;BIX?Ew>1U?Gj?aKtR@bfF2HQ0dgCxuXHu!mh$Q8mIrj~SEpKTP!GYNZ$lHv^@X_l6`t%0?4n4-+8XInC*P;c3@Y8iM^5vxe~}TSV<&ijgxAmmbXQ;iW11Pzy7qsztGc+VQ}B<4RFdXc{P8~ zVp$ihq(E#niyDDMAx&aK;`z|&5yK`KcMMhs)dFmpcwW(_HC?MuSkF6sq+FzCToUv$ zS$lBMY;hovUy0NL3X`bYa-bCiX}y|EP0?6cfLT?~e0x1?~G0 z_#>WIlIfHD^-t9M(}i1&1+WJ|Fn!XlcE_@7(#&2O$itxMJKd) z<^%~@HZK&KN~}7W*doq)u@a*$0SUa-ABhzq!`@YunMJp2F{l}--xTypbsB}kio|Hk zAsU6j0!^MFw)-O^w#(k=R2*Uyh!gr;e=IfCsT7tXFbPN2T)9)ztl6Q+Rvb)Jx)E(f zS1BUP@ANA}WPF#;1mlQ=%0xmWX2_>SC+DJnx+ZqHb zS3Q=g^WW1vh>Z%lWhQy7UcLmZ%kMyyD6_OZrU?xh8BGUD6Y>RBq6`jbyden|)K}@w z0_Jqs9)akhOgrq>h8dwnH?5AyjUG+P6y*aCwgW^V_Nuk{$Q2vaQJB6&T3$2ywJVW+6nIi`@Y>g*tT92uY$(jzB8DiN1_DVkxjM2hT?TP{*Qk$)U{F~mB70Qf z-hg$OtqO%>wfGb%{$`knnk0F#eq$R*VBD%rNO`yz8XynA2kuo- z=N;hc)*$&HW15a^p>EUl0mwesarvw^sFgUfTD4S{s9ZZG}#FUMf#;$*cyD0bn~D z5;SZ}-7$Q!V~{nu$?@nT*wlJiTMVtNi7=vk`W*zFGdI-?&xFvP&FqFPoAr7{8oglK zLs;il?LPQ}80%AD8BL%`;h-%vjm$@B0T9)aL^uuGmY?NN9qu2A#DW~GPvpv_38v`d zPzt4>t8mb+ySx&>9UBtS++)o%Z>mFXa}*03m8?oc*^ItF{ORH3p*CYpID-z%J+THv z)`}D86Fm_VOG0*>*%pV>8f;DpcA}}8niISwb-QzP%6C;lCICBS8l>L(Cgd|j!N40H z$oAi(^S?9d6@HP4cm^wC49v6$a4GOHe}JFla^idgjXHC!3kTFFO)vsJ2(>mpSX*%> zcj2Zi=0|P{A+4oKa(Lm&-Dujg$gizf4b@wnYvD9S`N@@xh`9s&L@IJu84Du2#E85Z z$59sg*)BmEG3LUwJ6~2dy|i%F2la7;*Ia$&Z39HJFRgmTnwcsdYZAnvy_oK4IN-$=goFCTAO>pTX*^l}3f049SfHl$D-r?zRbu6_p*d+I z!#CF^Y?G5_jr4SK@#lEE!wM7YUs?}9!i*P2@=T}97acbQR8lp6)hIcOzM@j zDUZMT?Z^P#GIFEjBD4@Zye<({58u_9NYF*5BD^gNSOrF{5VBZxM} zEl@sBW2%Pi49ImwBGR!w`4gpHNP7oyaUs- z=)o726y})@eCFrVId3!p{D)g2P1p%3NfeGVae z&LSO)U&5j}0@6r2ZV7RKrT_cB21oJWU2|8GEcgKFuMq_~4xj3#o4YW28y zK}>v7R93HG77b?xm^NB^k2Fhp*yd!AGNF(lT$w>eH@8^gqA!YsV|)6jJ5Ru`0Lmmyks^G_2o@ zTFNRhX<~-O-x*WrS;N#2*um(wKJ9De{@jZuvT}~J3&+h1Ae9ax3eQh47nZ`BhcoDS=O#S zKaEL|*0job)qCE)#+Mg^g+DjRO6c%=I&Oc7bQS?(b+<^~H_r2oJx|*u-t)LsNy}_( zwwrq$%eJ1}=33kFXPic6K5ZYl+pl*1O>0$0a_g~}Jts>sqhC+)zPv`iWf}sToy5*b!#vN&T-Htsh#2llf*#ke&N9{= zZ|?0^YFpoY{jn4lKVOUe;H7b8atz#Fwu_ClNo(@F{vPd27h{9LM%QeHKYZO(&j(k| z=D1&~%}gZjFJ%N0N)q?=y;W z-19fL;kbDBoDZ(MZEoAq4{!{(y8Nyyb~N9x>l_W*(RU*|eA8eo0{vdEGwpQgz4UjL zeT?w!5^?@xg2r2}uX0pZdjy|pzvGv0rg^@F$A?wBdY2dg>1}oq*#(Zj+cyG#x&EYf zath9BaJ}iB{+n+7t?3wsGkt3RYJ=??g74?}m9pLMSy9lirh6a2L1{~x&Gha5(Db+A!|Vr0TJN)$Osbd1UwhR2 z)GAj;d7sGNawPr9>8}Ja2;to%SFUvnD>1Slm3jikI$9LpLQ~D z&YfAdKl@7Q{xBMw?#<47jLC4D^ELF|8XJEuZf5XLbA8Ls-1pJbJwdkb^#7HyZvL1& z`jKsRir;!xuFluhc0IgS7X@J0`kmb^XY3N!=TOt^d?GX(Z9c6k`@I;o_CJ4*bOoZW z+kD@TJU)~wfUxA^$h%%WBBi@r2=^-I9xka>JNynyTZSLk%(b*lQf52M}6;H8x3nW{DCU4kyI zvs~b=fm|Zd=8byPLp6GsXD=ed%ZDUcce9(%+LrBphh+cXbmp6Nv#~G7IKPWOCo^FM zWB_nLA1sB;QCO|7=g%b@Q5)cF>4Ve%{Q&v*k;Z?H{~-VAME_$4z8`^4&+l?#tfk%W zM>HM*w)@(|R(7%(z{{WM(Pp_1_^|Hv*6RC=@Y&LOyzRA4>t~SWZy$Y47QQPBs|u^} zb9LGZ{JNWu>0sIS@OHK+m&^43vG<*0@8x?E+b-WHpp9hEbaR?co#E`(|Ftu;f^)XJ zS3h+$Je~OTUGGZoOVaeciaNT*n4RBYeeLqP{m!rdnm!G_!@lhUv>)!ro9WYhSCB_>wh~j74Zz< zL2K=#(f@>#6m3{N35O#q75G>$6E5|q&Cz0qZMfd3s?o8^*nT(ra&c;#JU;GnF^cjx z&%ZrRhCwZzZeP3Ht4IU(g$+D=a(}O*Y}QHREntzT=Dhb;%`~L*+FdC|Go4lXYdWLi zrjR>Na0nM0Hm;k!xuB_TwjH9gHAA;~nahPwa^N4VBVoi;Ju$l7L*vI^py5N0CRl7!vGz|-aTXnHA`~FAe+L#^cCZ(H~ zmUxP=3h&kNGiq!%Xa8UZPJ%42o@#_LxA*GS{#B_VX4#N(yC9y*ztXQg{H4*>b`q-1 zbB3iEi+rfbAy^!jZE}B(BI)brwdG|p7_%oB+e7CDq9y2SCMfsPEA7#|_9RZ7WUeAE zVR1a%M8Q?K1N?w%`um+V9zIJ_b$7ITOyNX3gu^qJlO(mFN7*)QwOJ^8Hj>Zn8a=+r zAo0lKChmS$kz!>h=}X`-A(hFn#g(_@UL<-P0aa~yRs+Q47zw$`v=^N<2PJ{L9q*1o{@O!@~q>3lm6EuPf% z=q0;Mx^F?=L+fq{_8ZsJP79ka9_4;ddPo0NN=?3tUEBoD<)Uo`E>&GjUyf5&wI{j# z4f3W1J$hgu+u?ENByxsL_-6U?81e4xB<8A&4~d|SEolj|wAc?9SIvrz$RWB8vc%t| zPJVsI=^ zJ_`OYE(sqIaH2Gl+m{2AL*lj~mua?ZgiW{K%{E(`mY0mP?*1Kp)GV?K;?y@?rAo8p zrDxFW@-gc9O#-cEWz4$mMS3(`0e)p4?be;4vT}Oa?{^$Ro}`sLzk&a=f;Ub1lh)B8 zFIb-L>>NF(-RC7Lv0B_;()IPkR@eL{(pt?@+0+e2LT!pl(EBAho3`2kgkziY;k{wU?(4FuTNNFf?%nEobs3*_3AZ|_M>!?6(6)6`Ri0=$GcQiw z_eMj)LHlaWf~Nwfrk8gqSJ{%eGpR3o^;-R7!7^bUra(Y7Q$_nPmzx9KH|uing&^|; zC5{=OiGC=Z{fg&vu+va0<#*G`v;SG1?56n;v(y{hrDClK=CfC0Ce2+e%t!BJ zeiSZ`$33|m$Ag6m2KDIR!7mDYlPWSR8bvljzDd8?8X0iO>bGlIy4M?(X+K99OUbe7ZXLZqXFErwE ze-E3+yj4C~-ea0hO>Vgknk|Nw9~o_?#q3ure0hl+o&IjWNSaE2)DufKMQ!rWp{b}L zk_t$B==P&6a!pdBZ2FBmd$>IPa}@XTUH(_^^YMnuvZfmS>7t%kdlao6&9&~?W=4`_ zQdF~;vU=mkYAWn$8?T(LHeoiwaPZ$NYI*%S86T;Hh%Isbe;0=X{NC=aVeY5$o>I`` zC0l+gA0+#hU!_=ZsW|GXdoH}woOr$r*8Ft29$jN1Z+Y%3+Q(A_Q9sBHajY&lp58Cl zeFEI1uM*p=RU^gbTq0+AvYOU3KfwkMJ4X!6)@O38T@9}@-Be}iglROmhGtgaz=K8~ zA8`8iR?pS^Oj$BJ$1e>UK#(n7Wqns}nJFH3{auXOH4Dps)E2vIwB~VpX(?y2Zd3o# z+Uj~HF1}|j4>ddLxhv_$CD+-pOYz=y%u&?6b^UD4?Fm%d9hQsxqyA;>VxIyGI7F=0H-#s^6V%%^9%Icprs9~hxh%qSS zk0F}`3D|a2%Bcckx|+LqWWvW@CLWQ#W~jop;ev=3tgu2#L{Y8tD}(b$F93|NW=ZH- z8R?}U8fb*ig|H4ij`w9=TW*;q)jK5=eX ziLvj#-6f`mFC+L5ZH`a^K?_}O5r_>52G9AE>Frb&OTcC)GK?f(es|pArcMoF#Scc_ zP-LJ*3fmK<3j@dp5Icd8_u%6KgaU$4P~a{|z#0Ld9)##QKo5k-q=A1DAm#$$62P4X zz!M;01c)d>$PS1pLDK~|D}Yi9U{(UO6di+;Qb)o2YnfVAO?|; z0-zb;PX~BBfYAqtH9)TJX(~Wn3;A|Hp%157NysTLr%gdinC>lQ%0 z1oh7$K@Su$VTKJjV!~)A!WXoE={;9w3|as)|{ zEkzJEV=4%>k*P%BIRg}sxJMuyg|3mQ4@2LHfh7o0LJA}}Py!hfEJkoB0RCsO!{6}# zrvM)PV)kC~-@lV{C?Fux|BC>wZ)jv^W~^^)Z~LDTW$Hx#KYF;Yny(G&8J7RNd)pnW zWXF3>NPse2{!dV9&zLMFPj3{fC0nYNUam$YO}mo#lLlBAmG+GpLUNt3+DGJ}At ztua4N;j#W~ZOWXY_A00_odyqoob(b@qTso?@gdXJ`g_bhY0+ErH!5p6L$Xuhkur;+ z{6cgRPGzq$Ri?PAiMF_s(=;eAL6)E)s_ZbSE)^!q5F2x1rA38u`llu*c?vwanpQnV zMKT>;leHIN(4?j2IyY10Z?cPgOS#ml3MH}<<)uigwo<9~*vfPhI|UkC<}7fvlxSuv zO*=exS20U{mE{H1Se#c&kNTRcY(0~V> z;;$NOvAmQ72cv?l07D`)XdK}zUxuPDwM09C}B0;k(pih5vCbI51 zaxI8JBFi`CjIIThX_jnkQ7hJ%N^pP$H*OFH|4^%~4{BFkVM`bYyD~b+yG9rVE6CbT z7gpB1EP`2p}HK5)Oup|`R5*pqi z9<8fRz#V1Va^>!65NW)ka{~n|ojUzeHJ^FLp05VV^b4gYejI}`4{^|=H>irXFn%r*nRYSePzEtmhI8$b*n!&dz7ctKE zZLr>lGWTuhdS7LZ(b)XaeA%aej(*UcNPPUrdY_6nN*^}O2{wOv-_!~Ayj8f}H{1QD zNB;rjcbQ9bxW9@$ZYN%jmSg>Y%3n*~b|qULH}wR+b|+z9)YaZWZO1U?_r6xW$F%`DdHOenzO?dIzCVZeYv6XYNYVH8sO@}K z&(8k}h}QGVy?yKN{y5dqcDbNYhcI8Lb9b}%`(n%UzUAh^Ui$kw6Ask(o8{STy=`8x zw;R+Nz~%0L&5Ysl7Uycrc6Y@pyUWK;0n5gGF-h#TrGO`XvS93QX;ODs#%|VEucOf0 zZ7(bPf>^~Fv3quorF~bwBN`^#ps8~6wJnczVx+iqW)p~LC(?oR6p^?bWyPG5BPiutu zMj!=`fOtJm!c&+bq<-8dah7}Vvxv-o&b_g@OEFfK(^YP|8!+@VffH{N@3M(&OfBlU zlpgj3$O|bos}!qB;=5o`?ELp+A?`905W2Wil9T4jY_(smC`^A`G`EY+`YiM8|7{jA z5FbDl;8oOIbROnFo^GibT`2LK;MIdx)bevU;aRdKOFuL{LcLD?13xI z5!|dXip>}1YGZ&pf54eD489Yd^}7!s`sfG#KO>!{p;8+Z3=mMue}5wh{;!eF!9m~E z#nQ(4e+4;Lbzd9pRW$$kH?qFW9CBIy$E~wA%iWQA0?8wCA_hr33fnESl2BP2 z(zx#=4o91Hg71X@(I6$3wn`P6Lsd{!yem@51yc)QnQfS2nbj~A(lPQD!FK+I5?O6S zBmV|Ox49?hWVPX?2ky6=ecm(ox!$);_xFQc;JE637EHVieuWu&r<^0ExTDXjr!f~E zeysTua_Lc(t^+Bw8o|G*^;F%o&CY9-a^!Jj7c$hgCWp~sjQO&rIUG{uWfzSqT$vGP z$wEx}f2+(6FMk*<9Iyqy zEs6r#xC|6EBu<>fP(T}$$Sr3|{)#nqDa@4rZC)L{4oakoxUks)kuh3qDKaqeSxcjl zHeqJ2)C}9@iu0PKMz2w5lq!vJi*1H0!`iHvS(Dbf>r?9?+xpL(3bQ#?lJopg}_NhQ5T zBQBwj_NvkGg(-GfpW@WCyp9Oy(-9jOABRyDSVt2$hrOPAhd}!4M2nIwExFL^DNK3M zT`yE<9;u!5N&R^PWzBXE%v*M~LxA?lHCd=$w`pWwgEgHEXyOeT`C1a*z==Dxl27r_ zUaO!<76M1!aLaPD1iw6KcyDYD6;r`f^3XC^5{KvuJGA^(%Yv6Bw+{J_qqc|*X|ITl z%@Ug8nkb_DiQrJ6M3uZvN;;WtbQJ;$8smW})P_jvGSY&wAUq0Lh=h7`$;E~`EBa87 z1&PUqv`5!i$!vlbU5Q;)iJrFHZcwE*qiZvL-HGLs)MXmCl78R{-N}lzx{@`KNLQAt zs|2DTv&!zO&@<6QgWST1oMdts8YlUPLAs`H8C?R7WG(ZB7hx-cL~Z?YK+1Xv&Qyt3 zq6$sYRzWn5XP059$`uS1LsAz)2^$DiY&niS#cEVZj|d`k*Cmr>wKA9f&zhtJhRH6h z412&fAfqHhMX;&E1Ru>ELbbvTE29;Jf)qAFR-g?{COd%^xG6iZhMU-qs9W%l1OhBE zbiz_e6=7sBpCTDO_?QEE1qQ9R&!Jh14xw*RdU^KC2K)w%cFq)9vK{#E&!gkWZVSB8 zn-IHOI~D@UE(n--z=vA$Ezl`7<372S@`kyGARJ9$ z#x%~8kh?>kwKQ!>_n*}gzH&ES;x<89?nvTT>C`-gE7DV|Ffb>X*2DG>Ajj&ST!Cs5 z;!lIT`O8pNNmO5_c-qe_7xm^2U(KDtHttrO0Sk@vMCd@?liEMs!dXq1`fv7vR z+=X&Ft8U3|0`@))#oSiYcViotSFRG@awlcvVG@YQ!m^*>i~eFEbf@jxb)00>FOk4` zR&8WJX%Kl3#70P7NIDmR@^C|9*XY5Q0od3u(St;Q1R?knW$czd;RIC9P+4p+IpB#k z&1#D->H()rmSdHQZ3;KRX|mjCn1)|oi8u1=HpXjzjXnBy5J$Jn7Sz-5frVIeJbgo5 zM$NSm{F*Yz>c|{q_a_!&OPvo^T8%$$M>Ky@@iT&Sykxszja-Fl`lM=ZooMllFJwQl z9_nC?_~q}qNYwgYYC-Wq;WJo30=o(pgFEJ3*6BAsx)Ck@?70b(-vFC~<#;OlyJ+i2^4aFequuK;&u=3!AqJre{-Cy6JzaeX^0tdBh8~A3a z`Q1*PLHU&yy-w%f!bTT^DDIG_Q}T zKg0ZXFW~dW^&Z~yd%{b^$Ko}*e!&G-yz(4xSzT$2b7_xrt#5Iy^^dJJx;NpW0<`U~ zSlja3y>A-N8!4jpt=W^ZWhs`{!IAPEOtkbi96*FDBTv z<9NR#-maNH;_LW)FE*3?H`c$J=YPUDho?|%x* z-~2sX7~Lr!hyFjGJN@SR8||+rvIIRI7pW)w`%j0=cfK9ZYk)I3*R|j8=H~s}yDrD~ zT|f2b6aL;CPryT>aU2Cc=Gj;ibPcEF-MC*j13>W8#+N~2WbG}$W%H9zqI{QsB+RCF zdk<&i6=35tF3^|}ZoWNi*)qeKgu5qMBPe#*BA@4bxrKTgo$toR?)NpfO7iq1T%3t@ z4^G7b_R7YaEQ&r!_{W~xN!b+4x&!50+Opmy1|PD1sRn44<=%dnT3hd%i#S0WZXH0V9CtyM`EMQ;E-z)+IW~oOl)JYP0sEt`G%nz0|2Ev z-ZxXWk(5~@YPLx<%}_MWSbW3LEr@p_ZKL>_lzSB4eBWT-OungngVQatcffBzmB zzahU#zkz+DepCAz?-l1&`<1)y!a2iv=NIVzB#}fGgy2#LKtLntKtQwf(P9sPNEjr2`I^SEl#<= z>klKZE3ypA@_bu1xz-X{E=~_*uGuTgKCLo!={qs=jm)xJa@>|Y%PhU|ojKm=r)31o z7r(V>4V`8)Gy0$XZ+^e^Z@(L&#i+`=aLT`8w0tfm6EpRUaNco-8Qwl&eEENqDuoJF zDEAsG&Rj@LF9pqY`BlsQFP5V9!fs@ZhUp~d(RW$G<0PuEzcJVylvZiULoNh`HS zO@089KB=0C`)8E!u9NcUR7@UKVLgq>OpUA{?MlwI*(ESiv-tG2NKJ7zzlcGISESgK zS)$u!n*8(|m-L!Odkj(Fkv4~fR4qlr8EJw9 z30xU1Pm`Z-?|DKjnZ@|*mBd0)HYcTm4xg1aWwqfWN(dKKv324q0qe@za;}^i3x zJ3)0HlqpdPi&1e1JoV*j22AnGG~izAqtpq@&ROi~{p^}7u~l%RbLw8^zoM95bm~zKLeFeXtWm9&s>e!Cc+S=8t6Lok_i1f5Tb(AwkYr~*z4^L zw1fE>(|~^IkTZmWABJa^c|kA$FZ(hF-i2N{N2V<-s#ATGUH%_8$8E33zNc_XF@ z%gDq;5m6Pc;xMAplT=UyQ%k!<3&1$65Q-5OQNd{>?+p?{BtTw;$rL*6iK;3J;0me< zQqQ=KF8=ALRZN!&HQCUNfzCDl87+XzX%Yollbod+1@YtX)iYb}0H3Wd%YYWb_SI+icQs_l3aBzM@u|w- zAD7w*J1h({bs?B~zQGmPVzI`O;IU#Yh>x5W#)0#kR_J_?D;A%;w)MT|U>9(HH99)Y zWe3EhbLSD~2&)?pMOzhGQIwH!yJFrppVW(m-bro*FcAG=5dY7Pb;FlwR zth8B}D#f$RtY|Rh>=x{V#?0HXB)eKK!Cf!j{sDtTM!y^GZwrj^5H-h-7frzkVAps1V<#F6h5*kA3IG@ z7P6qQNMu_Na>F`6luQNd+&bbuTO^`zaVWPyNRijWIb|Ok9|lqW?cu-IZ2={l49W4Z zP-2@uhQ*YlQ8SquiXJV&`%Yn3YURVK3R(C)qwb!qX`v+oq5|dBmgj@Wsv(DLtK#!j z=J?9x`K=B}JC-3TBa-(_iS%SWni;`r@-;;shksFyn29}hPoBG>eJq5JYb4TtzczUt z^2(1g>0sN6cRJ_+x@mzdDQd$&qr8PA(8y5!c^U$Ty#x1eU%JW%zEQmF*}WT38qaM! zEq4H59)gw4PaoJ0Wg)TC9COf2JEBT}3jK|mCu~%!W}SyEUmd}wyn&RJy)sp4xaZTb zzdOiAQfH8WOX+~3lGp({_N#9>jX{l#OO}#Q9Sm+4dmn4y1+oLN2tWYpfv!|H;}N-`!l!k=uZ_UDJkmb#BdiotH2MoV5s=jZ&W;uAkqvkU zDq%N}w@H+{M&KiKdTD?c0@eh9_Lo5?JW5zGY}mb!dW5PGehq0QpiH=AToK)=Hi(pS zSj+44^U}3FK*SwAPrYuqr|jSW@m)ecagP!{ymx`@x6X(bf7e}3*ir;H!VV=G9GzA+ zqQH&TdE?8pw@>H*>)#G`cfG&)n|^<=J5<6|#RURQTO*(5Ca7vF3dvq38y<>k;0c%2 z)-2W_4&@GY`%Jha65Y$CgJ2V5=W;IymJ6-ua0J8!mRtf(8vI-s*iGw$se%_6i!_6( z{Z3gh)~}Enu!^kFO6`Lv>y22_8>`Ndc=u``deSuweN`rreFgkQ)REsX8gMF!DTUmM zpgE%mJdMAjy$9~?UEu`~7y?GzgS7>tP*yNpq}&fbKNe!_>?m}i^)_gkmOB#+GwJ6Y zj@!zGJPHtY6*HM6 zuUNgE`9+R)Dva;T4>+H?9(}`G=?UDpd16b4(bUU_m1WY0mA{G7ZQ@~3-Cjuqdg-;jap7W3 z>z{rl{#48lK7-ykPmbZ{ZDG5OvR-fHJA63IoD4Ii?;g?5=%&Qy7k#waF7(K8IeFve zInH6@c3Pcnmn|yUjdeOxKe?WH4<#D+(C~km@E9+BE&}zvtt8VVi<2Ae4!vbr&wI>y zEZ_aU`(5-VHnQV$x<1vYlNaln=VSWV-puIhPO9YJ_j+FCBE}>7`8-`%Q(%1R`+scv zkCpbnZK0+!;Qtc5lDS#FT@E$2`!L}Dz#a{;^IO%$^ru$f_?&EfGhF_NNH34G3jf|( z4}BH>`Z*qUI?wYpysw>Y5%>YRbK`aJygaNs-kJfw@9(Ai|AP9*TF=6^_5lZix1o1e zH`V^1PUe1R&z-B`_5Dvl?M`)1yOn`TPo=Z|$AFjB^dDL81A_dEuee)ntFQEY7=Ek1 zjwk3pxxoKY^G?`ghT4flJYaz7jY{gOw%@_QPTZLg#Mz8*d=zet?d z!X9GyUaxEa-SPmG&W}G?X2s9v=yi@yLhg2NS7sXbCzjW9ei@d1^)t>|<65l!3&-`0 z!UD^3^U%sxMhIKGK{n5S9n2VB*28lAFSFI6|0wwSUM20d;?Tf?0W$a7tH4bhG1j!a zS^jJg!OWQ4#?`}bf(8D4&y`%dG>w`CBA52`T2#)Uj!lQ)I!8{|=V0mjrGNMJa$Y_M z6Mvd+Kr=nooN6zdVS&Iq$_3OKt{z8hPXb+pJH=I#RTTG)$E|Iis_9vLfrla;bqB( zqoZYLn2Z<GgH%?;46yTJPjpYf-axMHz@-4$EA!5sn-?-pVgS^^XZf) z1rdA_iOa0Z(i7<#m*MkM>9EYb)1X34A_*}y)aH(z`(bBuas`CB+Y#%0tzprkoJKy| zty64_Wcm0fFr?Sk_YrZtv`tyRrZ`x3%Sf^cBZI^cpb~VDe|s0^T#y6`{kCTmfseOm zS+eLP~DaDPB_*M0!v{*Oz- zCx=TWn-F6(;efJEBAaYFo|lL&_B#G}H1dG))zKliLrUj&b=>kO&Vh8DNL8HcsIx<0 zhb#}FuV^;WHqkaI1SR8Fbwund@Bf@ZIrDW&i+(73Jt!a`lK*uEb+lplPsZNTYJCZ< z%WH(xm@-d@BVvEWn1t?hPa@x{Bq{;8v+20h=F?)|3Qj?_xR5%dNyviqkc>B?aD1*X z#=19~h(6b5sd6O3+NKHYJXVjt7JbvFQY6mBoT*Yh(ip1-7&yY9-_M3KrI-_xT4ZOR z`>vdY?#L4jGQ!bEI{1sA&2HU}=Bn3(1prwBFB%X{o+xd)Vf0c){K#q})%L4w< z4^Ium(<#88ry;KSC;R5fDM>uhPul)iI6BAr_HHk_@f zzhyHv5mz}RiVi*yWxpOtEoVsSOt9jjv7B%aS}ZjS?x)<+L^aw#i?T1V{~}H5bC(SG z3(O`l><>?lI#EnNJ?M5_mn%K4h7V2Nx*+GnP&8AX4Boi)Om3s9w7UQdPpK_04Atzh zEbJs?T-E>YDB0YMW_J@=X{N2vEuW?|GBuD^c`8TBk4*L-)LlHfv|W3v8F6_3ndt6% z0iz>K&@33a(m}XAf9D38wfbo+#s0jO7C6Zftw8laOS2HkP zKZVR9QX)oXpfQRY|D-YokLjqLs{As820KsoxJQeMeb5vNS79W=T{sh2;g?YiR{SIJ@nU#n$0j zbOXdaBL&T>EoJ90JX=&s_NDzmfDrb8VF|&^Kz;!s5rTjG?ePG@85joP!9U3Lg3%M) z*~YX(%>c6QWfR_KgY@FeHI$xO56E=drUmX!&$-L;n+B_Ox@_{(ZCqt}Rc-W6UK51; z^stxPUh3IKUwN$rfi8v+b+C>`S*wb7k?Z;j@UEV58%a^Es;09RQlP=r)LgcvL*Xx_kdYAy?di$++ zgpP_gBKqsapT~B-HHC4wOPBjW<0>k{wEBTZ)64xkDpC<9d~{+aEoR&Ed{+08_hwy^ zHetCgG)3oQxM;!h`D1q*Qb&kH#r%>@+aZ%;yEEiO7E&QL{&BNH-(Ax&uOBAP>3r#AoR#`!Vmu z=qD5!<;jdmStc0EFv%#Z8%;UFK*_jjY~2p-gGYB~^V}P{G{-Mz-r8Kz9XeaD@H#8_ z_b?!y(L;ux{!NpZ57{kVO=zcWkWbx?hWD&K=-CYWE$ydJ(;%(`@7_}^WUQv07UN!H zvoNkJ1!25%YtONrpFf28H0uT#vRojiiMH3hbyi2=JS{`sP{jv2+bH8;?ci8;GCAH_W6lBhlJqoqwxRH}Xirx#~i;&Ef zJjAe5$O<6~JLiDQNV#dG#bd<4%{9hyo4)Ir1it@+t_K(|;IbhC0qtP@A63pk-_iI# zs+>BM9nP}*)?vVaCt`N%K>%@?<8MAlDMc;h+yTL4eBk&Q@m>&G^#&S5uw+yrts$at z9;{UvCC;f4@k=+;jcBqo+-!D57SSyH`BHn+H5o=lVRO!GCoSr-d6}4o^acAl_OvI@ z$RapN3zqu?+i%bA=kIS%NojnJH9GN4TM@D$_!#9#cX0)sWKwet>I}y+2Zuk(3<;+O zU5S%v#zk7x%xD;z6F>LV?35=qyy^iW=o1!qQubAInGDAkFby^t)PE>)kF=T;02FBV zKQ>J*CL*cjv7`(2gygZoc-q3gFDoilCe=l0%SEfIIo2FnqxkzUE%7PZ-;?)??QIz1E-P^K%o=&bIi;ef>kc_~WrMg;5%|=@JLD zdD_h5I!CKPLl+)PlZ~W78Yf1LA~ougNu$QpO0>Gg!Ze8-9cAexVI_UBffxZQTV(%u zHRi{MmMPTw;HSDYy6nclqsU+*N@ea%t=CeO@lT5EmV4?Ndc#!AA>PwOZQ7rs}fk0Cw*dlO?HTFRBbjG(ST7 zpEkWMd)?iJ^}gsV-tuGQwk$ayEXQ&*m80Hb>k-&)@Gf87$DmR^^d&t35vPoluKrWfyAxY|!~*|t6>1p9#2u?&`~?2p+*pt3}nBe)S< z^B|++fiv5z!BAr1Qs;@Ra`|^X9|5Fwyt1UV#rA~p=D2%C+uIrgEE{EI=OpSXDAk0VVbUmFIhre0r>nU? zAw)2Z)0T#S?52tKW56vE1BDJMSIJ;&Ow40BF5;D^d-W6Z zuwO)svqj|yi5Bpl9xSJwotj)S%6Hn=9*?nOoW2hnMY7}BGzMj%vag+6SHiUrQtY6K z`FFnM&f+f{%?)v%qk1l0C9xw2xAG1Y_(VDh09Ok#M>-LGytPPqaU~+|1?7mMXhq%y zEg_p88_ns**_>GUOD>48LZz9ToKkK&& zWb9+5^bm?`2+M!-Tp_dedyl&_Ng0#L|5*1zzcuW{gCo@m8+H==wD~;iq#;azgP0IS zYbrxgtB(SOb+>Vv03k@vJB3})M=S!t zvQPi`AW&xdTOM_S+vYSx3dAKU9DPU*QMms1#1dsHCq)t9#)B_zlr{1Je|>7H1_bo4#EX^z|J7s+O&6a+P4AQ~1qjZhcfFQJ?jv;a{;kuAFii zSd|Hc8#NjpE5@=?!&xNMetM|qnFhk?Q3>KEVx>snNqrOL^BAZOxk2m`6pINeG$Sp{ z4+ts9wu5xR6@+ZmN9u=IFKPgO`9iA^R(#xsc=7{nlJ(P`i){tsT=>;Q54)~+jsE{G z9H4exvLVqPd{h;J{q`1)E1Nn;S=N@FE>w;LTx|;6!Yw=aD+T0b`u1tiSUy^L{}PA}(>Yd#qHInwAP? zs?{351L(rytm5Rsl;F%2RO!*qTMdj1vM*fD*=#uiN2=hJV`PPd`%)Sr?MH{+b(-b2 zL32sdV7)PQ5LWX9@lxRp9uhibM0FP!wqLDn`v=!wF8qKw38|b~A|J<$3N=4)8%I`v zo%(GqN+}*ZX_5JfV)(3OEjM~9aya-ik!pTk{=;c*h0-rG4kKH^qGw%96$a?7|P8 z2`d;tlPTKlJ(-0e)Rf4Oa4c71;@$O5tXji{0uhK(p$N0ZRca|rw+NYw&4tVg}D>ufG89Bx> z5Lt-+5b?Y>h_3w#qo1e8z}mEpBl%T_k#Mtu$Qhj=d5=(!W&I<6V5UT!RcaWP8ky%9 zF!?b262jgC8-U`DkEMzWdP5yRlVzVUnbUbh_JuC;0Ot+{+usWler=QMYJnZ7qGF9{ zV99KsEOiCrg|9a7m~wK+;?}D{VRY9k%KnP+>WL1(VuaR1v$h4G_Q{@`i9)}lV0SSa}nMCX8ZBHqb-DBrVbBeW?%7e~x$ z2z-wfE*=aqh>@}H_I4g%u&oJ@ibroH$hY_7=A4NC+Vn}jIDn8mrJ+qgWrWpV6D9HC zW|%mlzdaUc;hQ!%fuw)%ej1!H)`gX~fg*IREZhqK*+_&+$(MTJ1C~>p{o@cmT*ZIL z-XrWX94_I7$?T|Oxb!Cjg14nm{Q$T{qiZqAW!5hP$IdbT>L_TR>~b+G$!TyA>`K7d zRi0wHXW6QN?lK>qmyO7y=IWS#Sayh*+<%00D5TY)-eUw14LJwflN*#ZPwc z!kZItXwlQ*M{bYuyF{O8jMY;7rh!0a`o?82zF29FGGXv91_TE~lC{4~n^AnT7;=2z zN@O1*b>5iZtiB4^i7>DSZZ0`cnHd@S zye^VHHBptaP?S>s)N_DiXK$+5K9fn~%g8OjYc!~UUE(t4=j39AO_$lf;|yRpN}GvE zi3%L|UsQ@&jS`cA5b%d`F-|1gDbTEv3!?&3f%rBE8hJ4UpR~V@8QmA!U_aR-4r+;> zND1fSO0}J!tM2a~)0%0{jMXO&hvgY%M-J?9sO$-RVRv}seUW2Vb8Mr+xUo!PA_kIM zk9m5SVvx^6Mu#ie`|yQVU<5BH2P;S_U!0T&)G7qHT9gNyJ=Vh?jmo+DitG6UdYYj#+!bJZM`9(Gonl zY}|BB0m+hQCJST~%S{2?$0ghc6nXLumgR_kPCdFiev5Huyss%JFVPapF?hBDgb-Lq zG}m$EU^i3lBK#EW!mOWVLVw9rI=ko0!H11a*e0_&b(mTx?z{Q%Gm{K%QPJh|-HZ3Y ztna{R(daILOSWaStoRLraYa79U+@RuzWRW!ljRYw;Cx@#9vg`^9EE2BQ7D<7O+pnfKfL$?81(G<$1g)a$DIbmYZRSJ&faW!ei= zl}goz{x(>3E5|L1V7hy0^L9M#Wk9Lb{1gCcO$UGVxzMyyz2@^Mi%aWke(%Y>eIw2D+V{pLqr6Sc({P)^ z*vtD`uiKrE8{h16A3SSa@%8xD?VICm@4c>D_FZ?#L{6Raa)J1xSw+zK>#VSLWB5Hu z-nFg~uanGnVd-splC~E`pp7W(T$+l$f~n@R9q=p<*$P7$>|F7ME$M` zf#L-tp*~Z(e~(JB_rd|Sc3v6d@51@l-W0%oE1K09#<5p9Sb;UA@t~Ho zFZwW|655U5ApBO7^EuT9)6nZ)y%?RX_KusT)*P)|vA5a8`@4;gXEQM_u|6r_Q%V@nY7RHiL5T0v&`6l_xzVUF^zbj-XWv$&#Dbg_Bzk(qyX9-2pVc8TNz!yCJI zyiTs{yzI>J3HfQsiS4Z9!~6sI8`j(UgYg^kC*B*!8~EG%!}){d1I|On1H$R~1IruL zC(Ikf=bumfPLXce??j&rpYSiZPt7;i2kAFKkH9YB@3<~O+qv)j>sj5IZLlIe#Th(O ze%Tt@75s$&yxzs$Dm_;_YddW@gequ{K$;baiUtwW6Cdp4r7zypkN=2J)^pfO!2|^Y zQUU`4!u#LQbwev-eVhO9gtJx@x1Hxh#iv_M|MSBQD1#U!fl4l}FhDhg1=~mBRSj{*q7MDcIFt^JD3G;cJ$42N_=Is=2*FfIuUg{>?Ts(6&3=o#9d*8L zFac^ zHy~X93Bw7_)3B`@S)gr#ih{#dmltSKCSPr0UiOQyjS#RZH8BhWqY^#I3*Uj^PoL3t z6v*6x_r3L1(t^Zt0c%F9OaL*ZfkUnp?D6m4M!XKS*%2b#5)7bqo z3b6)CllC;oJZ6`8F#7xGS8{L*QqQR)7BdP%NK0q;ueomEejx(#WC1w0+#%w&2bo*} z2e@DU*@(L(#(arA`X*x87&luhbhnl3b{_zI1PI zKfPGLzxng}zWqGB%~%H$p|5X(+iswncjphd9Y}6uD_q`ExvCz2}Uy3zI!lqab{6AR*#=WO+<+biA%CO z@mOq>FUAav!6ers)2@~$+NpUtH)Wm)jU_A60AuqDPt%(^*O3p-g&7@Wj~<$~e>bIy z=a)|dBI%|c_*ToSgFo>rYERfxM;sC0a?Izj^=#HnZs<8~@ONIes^=>%%v`*vzfNY~ z-lRrJNd%z$dC%X6E8!s3i!V{^;b8gx(N?b5v;+3qy95^;@ZfgQ_4MJ=cm(s%!-(o_ zTCf-R`dC;>Nl+|AAIStie$BIa7bs;bFG(yPYv_p~JA&Iwq$@eRW-5(*+ed6?sw+!K z-jCD9nh}Pk)TPw5b`KpkCe2_14xs1v1|M^;))ChWZ_vXI>J!vQkJWw#8zv1B!3S;W zQu0OqM%_+aW_`^+RsHBAFl<)H6erSZfh$O7M(SWV*lmax33~f&c2?c>MtIBowI-Zj zG>PK2LRui-GK`tJR7va^>^Uv5h$tNNciUV*9}xeOuyPQ;V*~#YO~(FTqDezr8xwQW z|F+#Esd?Ms3_ExC`w#pHDv0I^dn5c!0JlaA8^;BbD;AsR1olf{0TL=MpN2Z050PB~ zksqiJIMGNm+=>G*Z-Okl@y`>>w0!N7RGL==P%g#0Cjz*XnQutKljh7S#%p&jnQxFD zo@{U~NsxJ8Zx8%sdMC?qAJ%NU{k7%U-Q4cl^RV%OIPBboDJzqmS((JfE@S72+q_e8 zM!jl5ruqkfzSIOTg4>+cyhON8*BP%w8>e2)mz%4$s^2_s6qvoKDceZusOZ>=*QQjp zY|t4yuLzFM#-JCbUUVo@qql%Cj?P#$(6(Ky7_>462v@6&EB8%I^rq7#JFez~r_rLX zXUcje5n*}&Sbmgq=~uzf#)5Q#XJ? zoTt@GszD_NRhm~`8{7+AC)!(^k9GUyS`Bt$R8`#{^$+zm*3PlNW~a2tSL0}pR->ns zW>kq9j|x~9jcP%XQStRfULug|0GROCw1?BBfsKm?sq)1UWtb!lPvvb25^v8$U?N%- zLvCen#cJ%gCXGjpA$|t{CYW|pkJk!A8rqBw1pte-;?SV$q_NLrEGfM=)>bqhxD zM(#a>mWoF3Gu%Pvn0?zj6Fj{BTWSPuWWU2mqAFVSx6ZA2eDWTMhT0NXbD5ix42sbt zZ3D$#z(7Uu*;(qb8$fzrYO-HE9g$_;Mn-EnNXHRtEQIW35;~Dl(-(Bi_%wuBJ5F&| ziTP0CvG{}1Rbs{{PcY%N;T8FY)W`i`UO*GuO!0`enUn{;0>;ppKO80#7o(7`^bc<} zc=5#g_jj1$B+@*iZX7cuWlPWj>X?LhfO`yuM0z)pCh8D+a0H$_)BrdOGR9nZOHBu& zMq)pYwYsLAB~&;1=^}_cXAK&eAAL2EoUMeOKVNnwI87V#*YA5g)nVJx55S7H{zX+V zywY!^HXJAt0$QSs>*;bTUrk9$5GC>b>$IP|qmKBo?)maB;_oi;84TO@F<(rS-}U{Swm?+B1Zp7+HVw^DiYtnPT3-BwP2KlgR zs{z7`5~QSKz|^f_R>zJWKgzn7SGtEfdp>rcx;q*IV05qF*IS9Jnw)EKk+u6uC{fZP2=SS z@F#||Ced~VfpSmjy5&VA(cpK3`~V;cM<8$-iPKQjbfX;6Ry-5}e_h%6T13y4R>Z%g zY2-0_q#rC%S9r~MvHh*H2{cnn089#laC9*z(9>BtU`D@2M1|LZEw@vN%Q@$b+ON< z?66cLAUQ!XQfw5_xDhjwIA&xlxE*?PD{9e?i#C!#_RalrOhepZn&{BpTmEcVrs&Oo z`wdnom5c$M@4eoZsKEis*(Z;bjxu$tuH(+&t#MCGq`A+$*@+M>fn`Ih4#v_WM&!WlER5pT*OwLKfQD8i;}|d? zyf0w5#Y`r!ocdUa$$suvNyU1>vxRr`I`5d)YjEC*S>;F2mUfNP5j^a&09&nAK-F`4{=bVSWnv-O1(ued5Kj^5ICD{JY@$kkaeE4B6DjB_m(*FwEI)$)u5yFiS*Oh zP0o|p00GLh$j=YrhMFjZCg-5ibhQW6H!|!`50Tz3Qk^I(c7y?mIhuFT62_HN&)Se z3uE&>RLNfAKGpRHAgYXwWn8G~mO4gxt7#!c zm{<)Fvy-D4bluUj3qih6TezTx|bG`jYW%iS=58Ud4YA(36 z=tqg;(*zjPhKlSUUd0#~LZ1%P*Ha8H$7`QxdFiTdj5tV5)Zew9mZl}r(_vS*XB5~F zFT^|MfZc=@ls3YVp5OyS5!QpzQ%tS@00udNj75Lj#+Ss(B9A-01GfyRi)Y>28Ic#v zwTVdILFFSqmDgIt->cDsI$JBz`1J!deGmG%3K-(4r3-g*wNg-GYXqzaP;ZU9DTGB- z1RUD;KD8Ld!`emrXE>ME()FU9xauwMox+W&9R4)f9c~`+Vh)pZO#QgnRFUuc-_fATB zriULAgqLGK5?fI3zIdzO1Ux*&^Pcf?ZtsOT{DVn7=GM}sT9*`D2fW~AJ+}Av8s%I@ zXI&zU&aQT?9-Zif@`h}$4HT{S>bWdCbq+k4H#5m_I;yq|Z7=71m!Je=-?zeGY%i*^ z@%WZrA}DP;`C7iU9>0t>^XB-TZ|VMO_S_(dduv@THtl+W$sv(KPNCj=(h9n;rIGAygk*^;tpFzWXGzMyuk-z0fnC;!%dd;civyv+GL zYHwG3=Vf|6Bo9&@g5-HQ+}(bM|8D2@y-V5Gea!B>*_-w{-^|j@NdMjt{YL8`*?PTy z7C6q<`O32Gy6vl$*7mv?V(WVEclEtGL3Zy?;SeoD+)c@G;Hd zt^d|%1W*|?-JT@A?>HHA>?@Y9gZLee@@VUOjWcZ9`IuJC^=p#0bKd<_!JxPyq7`_2 zd-8+(Py!(L2Wx`wPOZ=9cpURFD$42++tG}6+45DuIm_{!IvBbBCfIpOk>W7ou_ODq z$w$Cyi4OWEa1ci~^9L5@;C5teow7!#5bU?0;Y!DffDaBWfFpMxtBp-d%gWX~KGDc4 z4uXV-hvm-9x9h*|#`|Phxw=f(fs7q@DGj^{20IwG4*)G&qO;Gx}V|yq;w} z{#Hk#f+W(aGkJQhWn?$o)7QHg`4*uAfIAv<_nw)FtO#5}@DCJWVO#llKl9U})e#_3 z`G;+}0ksekYGi#onFZlqXUChxY6WJgIr%|AKqWlKy zovc&BcH;Oz=I#Fl_9_0R_)u~>{($yY{~-CG{AT=i|AV=py(zy*KB%5l&#gZ!pW4n< z&u`~N&w*9Bh)$520i{l6kIwhqSsJv@4;sXO5ax2d!nRcxqm&^99{)D$M5 zBgzS_#l^3vi@8VkC1Y0Bkk`>PS|h0=$7g~=3?ZV|hax7M`~v&cKV_t5(lU{iHnG8U z-Lc`SbHz#b+%@(2WwEM)49`J+byeQ|_4uALm;LGb2o9pzg^7*VVOS%d1_$=H9mKx} z!DBLOVzKU3ViInurRXd|>(#AEuF}|)I=D4n(^mCeyVasmY2p}rP=bT`lC{p}RZR2H zu2dYgj}`B%a)~Opg6%9z$ca=n-BFOGS;!O529QWC+dR0h-8IrGQmdpoaVH9Md8T9r zZE49f4IdwD^?BOOqey3#bAv_7#SNgP*hXUYS)l!AkXxh~;Y8jHPluowt z&n&2~a<8dWI{95&RUu8KY-qKP{#K(n!pRandkGP0PEf-y06Yyz0UR32jBM%@EKfqU zo71zZP{-#l6jQhRP(Uk!G9C17j{saXR5l|(BT5Q^2!WGY0=0z zBhHw_a`M`)Lq=xDw4jnv>joVP1lIL^i?n)u{ON3-wM3RpS%vvVFN~_L%KH)J9q%0* zJ#NF+8Pcc^Eaoq504im|ny%=Z8=G~Enm2}Ow@K>g&% z-C!eH7lD~NxT>lEYE)Uia+$Fv?ktDupBBZzI?a>PX=!P+7-3)k((2Jf#Nt$!K+4(P z=7tp(Ra!o${2i6^OK?{Qo4;PO=9o&3<59vWj~0{GSFVT9!Ihd0rnQ^OfCZdMXNC+; zo>P-eLpzcFON$7_JgVdps@e2&&%ix!Y3%^LccmgFipMu{$t11bXH66fNo=I1QA+8u zHUy&s1@8EqG9^T2-n=@stGnGeYuxHKr{XjNZRt)i2e(tawG2suqE>S-$Pf5X$B_pb zAc0l1V%`V-Nd7f=mY9>Es?5K=P*H~)mE%x?4*{7jiz=OlRH4!>h;!-G!Uo){Iso91 zSpyDTMHgdgeIxkFj9ew64?94kX8?%A-|HpYV-qDfgCA zr%cm1T-$)?*NVL7_zX@aNnAPxg*FNGDYa0=xr+}vylU$D zM9oE)^U)s6qTdakDIu`LVfm-k3wJxcGHcWR4UTP72CF=F;O4ZSd2aXBt5cg=jCN&7 z2m|Q|IB4?HO>2=_D((WyPqIUXHLu~hm5i`i%cM9o48@K83zc)A07^%!p7H{oVTr>GB zcRYt(eLVB~rjBtIWKX(`Z1+r3B}F(mz47{N;J3MJoPZ@tiZT0A%CkGLb+Agc_=f_A zj>6A+0}Iv6HWcP9X4f}l4DY|;J@f})AeID!Qbu4OzB+`tfIde#Cawa2X=jo8=3G3@ z@5$5+t1+S@bs}o|nqcegzDgo=`p{JU;pSA9SJF!f&NB`n`mv^%Cd7XMJ*!0U* z$vX(vJ)Gv}%0IvR+sG^VS>xl#?tP%K4DCXm9cK_@rU!J$7h8~^r3Qo%<~_ObiMaDf zuc5%p8I8x0PBI_h_TzFG%Zfsby@M$(s$ z^2|s}(G}G+vFckB@GV#aFiENpq7i4N*3HHkC{W&1{3Nrjf zyu-mrq}$pBJgr2QmBaKb`2KCpj8V@$gJDo?yZjz~hn7fLI7LIMA>^d5B4ma@0nDPL z<8B+!SiGEj(2RG`nC6kn9@Qs{FXg{EX_*+2M_-z%0s$c?D~7dBRCwoUeg`_xH~}fW zPj9&-RRWodp?HifNEj9Ba3_(43mQ`V2)R4UeGTp_7bOA1)dfO`mWWp@v~sAHeuMug zt>v_0>eaD8`9j3;amagTx!fD5SY^#Vpw$F<)ZkW)-m&e9j+5}Wfe5S|n0=JlcicW8 zN?WIpEJsfo$4)BrA6T%vHO}DAp?b{Lq%{{g9opa6A#1Acb}}?{H0&?J2|pTw!|#SF zwytOPF;rVb%#}U+^f6*B8yP@KbF(zsQ~Dhr0Zjp{mjG0W;^4Lbc@v=T)={mVGXk2? zI;aX#Z(mbbWA)&Mtl-LLLHvi6!P}HwkFrzYX0aUD9!2PH*GP+NgH5` ztydOSc7R3L{_Oq*y=GH;@#P43maPl#8<2O)=WVvZ9)~>Yp+zctQddCbV#$S-E$UAp z#zZ2U%6LhihA?(piW@y@B(X*^XXWNaO}u^{<^wI+4J`?+znXuWXtfg?G_>v&Z!J_8 z^?<6$*QC6!X#{H~Jw`DDO?L=25!FUh^W*PIdbPs<& z^mn;V9O|z~Mh;kUlCDC1TmqHh1PKLLb1?A&b`!Y_glGs#AQUPf{B6OinAN&i(t|Ag zVjZkVRP=xK__C101D&7-V7Q{F!?5fk#-PJbZ$DT_5@sWc!~hVBCJ%UNZ>k3=+Nh8W z9VWRySIjnYCPs5?b>L9|Lv{HRz;D`uu>hFKhDn_3&by^nPl?+n!*&#ZWV2t)G7Mh8 z$%6*I}{Po1HQlhK`2mm-Vt?Z-Vx!U&=foKv~_vkuxI0PBvTW&wz;d|&l9mV zo_)m@xy}3wKw&X)y>F3f5yHh>LccWDq<7!7kI53ZHs;PJXY74F?%CDs!$lB61jgEm zIWU}r8-e`7(4nw~9$4~9q3Q;%HL$}!oHQ68#%G^zQ54jGH?vh2d^Us}>4=oY57rAl z9hOU3iG*k-NDo%@!^acoJn6{e-xB5G(18BIB9ECwSrY;B$Ol8rHr)Ml!Nb-nTu}O~ zx!@$h^Gv4DeIY>NiF;#LHQ?k=%r?v$=j~q^MHmOW+GqCfaO?O%y9x#ekQ9&B&UfDB^l|?# zX1*%_vwtOsv-FbqmfAP05hcske)(_s$EBkKR!tE)Z0wL40!)B$dS7WMFk$gQ6f^C2 z!h?v{_3uO=q4eOEIP5Bv)3o0Z#Uj%Hz`e4M&o;r{@M6O^PHvS4S}*SYoGA4W}S{+O=~QfE$ubgXfDHmMbxylf74m{YO_K z6v(j`Hxd2M4Gfcu;><&3fm!GNJau@yWg2r1(^%{sr06roq;O|?5=~EG-W?r&fBd6U-Hb^Lqf^X->`ylN>ydGhh_?!Q;=W!DPxw{9;oqM3sY!kY(S6V) zhhR&p-#c49N9Wi%>v*_`!~U83<0JM14343c(Y+CXJuzwA#h17ic9V0yLEJy+rI?~+ z;rxW+)O_i>tN?zveA>Fq% zQ!w>GX7$o|!O+I#{&73J2IoT?N%$n}i|C!ndCdQkI_w+Cgs}T)zjpuf!4s)la=Y#E z0cC|dG~~sW3Jm7~wJtknmw_z1)5dz zN*5(ObjR)dkuPah<eNOt7j9+yqNpm$?7Amd^C_U1$rpP52@A;a;? zJ0HW>xwL@Q=}LuzAF(Z`aD6c{d!Sa(Jx8jls|gT=w3n5CIEi|JGopa*p=LUiFH)9B zeKLFmAMJEabvxw<+1WS@SSpR`DAMksHH0N#`vz+WK_`eN4pEohGM@E|zxA!n^;J;b zA}i|npat6`49W6y4IZ=96bHDk?U&?Ua+&E~W8lNYjPi#->mQYA9-?i8T9>a(bnBDw z>Q-og?$MfkyI5XzO1C~YjdikF>`6y;&t71XShQVZ1=?;YRS9?NUyc|k)i&?xDHL>h zjfSKkm#Ei6EzGe_b;0!(-d=P0U}N(FM{V;f=IKBOrSGE_*q^DEKXqJfucYG%uF1d6 zhIadhoYTO8#Fe&9bYeLnW9xBS&rb7y&@LDOUHu#84&(4&c7+_kQu8c+jIbZtGLK~H zoI|=+-vf>64sE|T@WrVEl!7d;|8mM9;VInlE)8%+@AcH(H;oDhY9&jKj`#0vShWdr z^-q1KL@3?$CZriR*U|gMUNFi^h0GmxaIH6B;(^I!o*5i@+3+Qm9<^rugioEelp`Iu z_GH<|NkKu$+>ek4%W<7KJl#`%T=NjuhKzD;UV>Go*9Mn;`_ex7dh(3#i?A@=zeqr> zDmuC-{vGOHzreLnV=~S<(Mc8(Dy!c|j_;cTPZXB(6iMe#F~PfU#_lYjq)lY8K{nbi zpOilmhVV;Xw>C@4Ymu7vHjRX5`NecR?RIfb*0p^A1N+;{9+WMyusf~rtN50VVsFx} zAkRlE4O@u>Wk>iKE!~bMm_xUCfZT5x(|ub8p?_DGALed`fXfH|tQ+WlIuwsOzfQ#$ zX;}YW)b11Aqvx?4@vCbUC(wFSK3T~2z~tWGrj{3udc`{+{*#4B-aK^S19;>6;|qa* zq_kRZ;JZ<2ikB}1Fh|EnBmP@7qB~&H*W-iBJ}Bio9obh>Cvm{{yb1MRJl`q-aPBuY z;y0hgry)n<$Bp}krSl-H4XSTUQ=GkgddRB;%KblV?k;~{*Kio@Z_dl|b5h+Rm(lm_ z^4^1h-H+}cXzXVLi?Irf7V08)jy`&7J>y^c)YYQ(llV&{4D=N{{{(1xiU&PqWlrlF4UbX=w%|7U4d|`!@yE|FNkponz7dV3b4OyaAdV_bZ9i^yid%6bRmt)82rvz%VMw zET=M0X1?L0$K5W7)b;PT4ea+U>kkmF54M12@7T0kDGpYYOou~s1rp*$3#QsZ6B4#} z4Y&bfLHPsL56JQ_r>by>5JnWp^!ujM-T;4rQP!zMh*wTWtT36cj3kWT^p{~^7FZ)! zV+jLP&=JdEJo5$Jq6*!h2(SaKE`JgCkNaqEz=T}`?fDbJBj3>7?BsUSWF5QRT54B@ z_7B>*#ij?^p^j|xh{*()$bTrGW==$gI@$A@o%Y~Q%>&)zXmbGtxboYPiY51Eh@z5& z>jqMX-_9`*0gt4S+DXI{uE&G1EK%YqBBPzE{cK$)$9t53`$1TiGAUV03&7{%$iBc~ z2~d?8aOH3s)P(DypQL94n+Ai4dUYtm}bMhXdGh396yeJ=qKD5d&Qv zuFC`gukG1ndU&N;0=n$kK?rtrU}p|XQ~)sYIu^c)uRMyEvQ5Ze|EbVi$0=HGx(5ua z+FON4T3|8hI{Q&^Rt^#Yi&43N11DOQnfN@ucbbO6%H7feT03MQMxBqX-z+eM=8J=d ze(lH|f3K5$5OaGz!OdXT9PETLCfQ_WG8-~-6DItA1m!Bw_aqaDJxYO|7#nlb0b&*tE`+S;wK}r}On#hQ&YAN(pEUc)(1JY+{@tUOlBnB(vNdd5C z*xSP>b@Sqx^;2VhwAM|aM_^rHq&Ox07hUJnBnY%5;kIqtw%yaVZQJIwZA{y?ZQHhO zdpqva-iY0Z^BYc7Wo3TZ{{=MxzPs!%ys|YP&5yedQ&ld+_j9f#S3bsW$OZ3l59u#E?(lCvwYdD(C{NLb$z$* zXTGq|WFKqGb)mVTy=GClcTmJ6gQ^qZ{DpbZf+(M`rr7uyKY;8E%U5e%HuKU)QFUq8 z-U@>A1!MTbE09v|&TZW_L{R2(@49_eD{wPH=4KDEztC5Q*@fea$#zhrWi1*cJX(9_ z+C#vqBUMbfY)F_igjN!mx{%g2iz33%+<|NQ2g09t+tz`TV>EtC4}AwjIH#hMxAzJH zg+wJVo1q!b8bvF@Fpy&>==0^X=ihc?X$*i8xz&8H?0C?b>19R!Wtjmm}Vc1`6v)7{2%feA3{OU(D`}b4xJg4zSGo{X*`P`L_=J)Ix-xn5Ey-q-7b! z(!D=A!tn=Q9e#JU8^Ck`W5%PrF3~r#Py1nX;N;p46M-YLPpD$yJ3W2J^ci#+S90d; zeQCz6EX(l?7Nu!3d%x!~n#7qamy-7enRh1{zMlb<3Gd;b#J6SN7urO-E5~(ysej&- zCl`UwtEm~EHHLgjpD!|Xop$vff5%#|isf#6C%@L1FQhpxWSYD6xfXMx$#&QjzLL<- zDlvV;tzPgJzGChkZ&2d;uR-fe1j|r|9f^{9CZy|UVEQbyapPkPtbS54O%An zjc$6Fd1A)+O>W#Yc&_eIrF~Q0)?*ri*NU93cj)l7<>9*DWPp~|=;^#TjpW0TXmez? zY7InA9v{2LxY@jo^;#?i%2N7kZl8aT0|~{n@15f+IBIGgHhcb`r5{yF>(!5~qhh`q zMXBDboOa4viZf%eJMP`}EG?n+`*#z>R3~-#9 zez*>Xmuotzq~56p8(a>W8YV28=q5t>7ri!1eUk;ZGK{7tscdc9zci+n`v%D1{R%mM z4lmc>pQs4)9!%-ID)Pm)mlTHRjTd1$7~F*nY^)uhO1YTYzr)d2nyfQWaLl65n_YVI z0;S;LH+h@t@IJ`l|M~fBx?zjI-i1_b>~O4^O?4R!g-^h-6s}CVd%t~J1+VN}At879 zF00kx_i&#--lSr6yu{SYN?2z(*Io3coWXiPS6^p7-=(ccqHXb?(`a^`*WtR|*wn-8 zEV_QXZhw>V+x+Zq)X$BrIAIrPy~x0R+8jKmi#bA9P=#LFaZ~2&d}D5rJC)3kpvaYL zZe3{<`OPqIa)0hzPgnZgmo+)49kRv`kpEeP*=ju2*IvyGiIhAtcxfD;VwD*gNa3p2 z)4ksgTgz`6ScQMMw$A!~DjMz@7>W3DrF}IW9H1`r3VaO7v{TCVB6Bz@)9O>IUMAN* zWoD=0tO;H9CN3SAvU!TxeS>JW#($%Z?Hs9{gGuFO$0$x#p)mqv8R(4p!j@1p9 zxM8gSApATS9XomNc5*0+n_HjPu&oJfaGE7C6P z{g}y4Hryd5wg6Tce7fW=NuOZNQjzt*C{G=t`>Qg&dE~;UeQy3tt}?Otjr`pxdLoP2}_>Kb?jwkDVF#yhnMX+SpzJa7Z<>N|GFJ^)Q=@VLAN8&=Y~NQ=Rr7`d=s zUSZho-}j9^n^iZf?{MysHREC_R>SClI3+brT`x1{8M>|SaPrSKe~PMtf(q*(48!%el3n(J6Xts~*p+EEk@ zGl8oyPS^wV$Wq!^+xQVbRG4{T&7k-8lsqxB4jHzGns=MYzBBH@O{AUJsB}_MSN?De zel%o|EmrJcVAu@@pQXD6@sEZ?F#CwosEAlJMPQ@?@;&bwo}GuXtVA_=`6RQ2P|`{w z?>4r|@zkAz1}CYmT;T|}h2hU7(|bl3HjIPdweQ~d>%p0wAy5=8F}?gOb9AntZb6w-5=&9qQ=s-Rx&o_Hu=a4< zypB`6_Smmleo^&)TnF;XT{;dJ{t%nh7-D;p>u4o=EWEJLT|{>lyugNAj?8GW{qRfJPp)t9>`?T*V0TL0kcwNVPr&NFrB~!nMBUJp{omnUJCuEY${l(; zqGd139eq0#evkN-f-eO74$>PbXL#z>YcpbIFXzr=GsJFhTBFq0(ZPa?>C=p!kX1R13<0j6|F{2oc5aYDQ?i$_cpsRl{L zVVw3pp$AD0N`j-Jgf5ZNC<{~IB#G1LFZhWm_A{|lM3)e?5IA03Y#y@1f#*6D*#RFV z7D=AS6Y5FOM}fc4f$(PsP=5CZ=)a8-0KCCa_s9SMt-o~^g#WiO!qvp_e|1{;{LYNn zOUc=Hqsv_p?aV8ct6Dg#`V=;-lEF6?F z^#YR_f15!lXrwZP>c7_KX-Ti11@UJa<=<@^W)76&OggU0a-At1pD4t$)X0n`S zIA1b51bWWO8V=_LJ2^Jk>#Q2ye9g3cCMqt&9o4U=}kS3xm)<(_w(#FGyHJkYp zaoH@2zUF>?)>AIDxK~mZclQC(?fhv7NSfOzGclH=X?gSNREZ14Ma*wN6;=Fc^VaL` zOnR23wMX}9h+0fplc^b0PMT=3Otcvh#mLV-z?!O3$EW68)lcLLnw>1Ev8E3}77}8i ztQ-1dY0W00jm{oK8JM`?g^lLg6SB;(Op`4G+2YoEI2n&-rEPKJBp^|Wv>8*zCBi0L zcvHi~!&VlJ^odg&1!v}#KY&#%$&*J;&)>={IV|CpF|97^BoB+5s5u$Q)3@vi%Zh5h$dAGR3@mvjW8Jq(rj&UCtzX$Iyi90EX!cf z_K(h_vC#UajJX(LKTy=gbI@>O3KM)x>i*6>%F9MQAKkB+!rN?C6h8+SDcY)gMz#cO%qkp zC7OK^8|2QPq;E|%P2ISb6)maXdd~`3IbkYt$K${HySP1E z9{c$lMy@D+%&2PpoRxR9mAgMNHT{P7uNUf@rqmK3w~Gv2ytZn`wxkuX){J+|b*Y7Y z3Bo~ml8#@@$Xjc~*JKtQe}d{zXO>N|3shOOT;}&1D%;EDIaF6GA~>oq71t&;p|uT2 z;Kj3#&p;E(PIPdNV{VAjJjbi@!)nua14jK~5}yn7Bs1R%j5dQ6W~ADc6*={ek{wl4 zj<}YNlzHh`2`Y3ms9v3iu8);V)T*4ynsd(+r8dT`Uk*F$}$WcOw+LZzsFPLJtZMaY{GvslYdW;7J`>B|k^G{cmuTUA1XWNgYW z7fUV^Iut4qaO!=>r^_k^C9{=J<<>Yw_(R>YmEVV`3^+rO5I8sq#H&T?B(sxH+(yyZ z7Ee#E6jQNOjlTkP&YmKd^lRu$Yf{Kn`YP6qmq-B!zw&i3=faIo;G`l@kR-J&S7|F^ zDnLb@<;rC9`pXibGDx=bp#G^Cx@O3M$QvvbaUG9ZhQIvlFN?;efrYxL=t7~4$AnzSNTQAKdfwE7q`~vb?JS{9P zoM(iGSbQJEtVaZ50=}yj2)l?XenHAvBEE9F8Pn_TDWoC#^Nb>M?O z^Dd0xSRmG&N=%!rOysQH<;vEs;=-bPm|=ZAVf^-p@=FoRoJ!R27bb_I8MG6(IUKWI zs#{GcFI^bp5tcP@gi6dfKs>oOhC7UDBh8vLn+7z~vY!N;o$cg2*t@FHPj?$Po9f!-G`vBQ@AG?CKOkyRcf6aQJH! z(;7z(-Fpa>CwsdA_5qek= z_?0P(wyx}u2HDta8AfAFM0dNgL8?gjghfqQLJ)LLFyu(fvma2JW*r%4T~4Y2|B)6L z={yerzGYvVr=1XmqaHPt+B!rAW`rE*P$y=6IA+M|z1kmB$F3?lyFk)b)WE}51sp5exhk@Ghy`BQ3MdSx=kYK zBzeoJiK)AlC$7|x>Il=^fjK%ak3}#cYHbtf??AU2LePk+W|QHK_S7!y)=nK_!XWkBr0HTM+%A7nrd$WL`lW_$MFM-V%HhE{_*8YX)bY`!57RNY zLw|Z+C~_d`sWsXD_rtxQo;&C-iGmwJ(#J$7w?I*YOdPEVGGqZ()xFAHc^_Ir(6b5a zAkZxd$w`PFe=N`fS-j=M6cZE464bO!n9hKqmhQ63T`@I%lyoHuEB7FYOJ<16Yk(rF zJ+ZVN%eEpI&!z%dZ4f4}*tG??2J<$YHEC|qZ`-iRhNhSa%5WLE1%2(ra^V`FuMS?a zs^PH7*5=X(l)o}$J^J&2lxg`&1fybbD*ddlqrj$_V7ZQmWbbYt)dtl0r(ZI3Y*S%y z(}1Zau)sjkU>=B!mPVRPxk*;mxz1Z5E>_T4rB;P0Do%h)!^*L`MP36M{oe{9Mql{#{%VP7`3GZGLLq4K8aas_}8J@+6i!g3mcH4sF`HoVZkzW_JL#M1uYCcFnL zVb=&Rm5EmRMi@oDQ%8#ItZIS3G%m~%3hPsnaZm=^ISF**Wux^o^p?>H#?2#JQUc;1 z<1x%QRP2tRQ3exgoHI5hpNjZ%9sAY_j-`%6i2{oN4{Xm7nq?Ln((Sl~3s}h3kst|J z=*ak*EdT>oLaL2uyvO-vco#&Fym z4$>jk!&H53V~JN>ZE*D&gdKrn;}m^(QuZN}$2X{#jG#43W3mwSiI?qX=Gz8L$d@aD zKGg~%9l3w*B6)lD%^1PBO-68BK^>FTLqXcsP4Eyq!abqZJ$sGF+NZ*%XlSkkN$MJr zE!X-Sx@4aXZ)7pLDik(pZ(m6tcC)4|9o#sp^+}i%%Huo&UQ z{h@As*NWKGB#&@D1XAsB$skj@Yz%M&gvu)){}>4@&q&a!aj74L4zk$mKM6$;26VbC zVV&QYItkq#)Ze&4Ep@%^5)qk&WRJ=PK4+2ZL|*PNN)IP=Lck1d=|GNHNTBT2@VquP zjiU10Z;&;}-ZllDr~u^9z*tm?CH}YH(NCQmi$xE9%7TK$Y3G#s>jo4$`fpaeL4NOI z&>F|D_a~IYboMyc1l=3&E)sJ!mGYSrIEQ(N4_^DuV>i&dTaaAhbQ3m9qsJZCdArxy zF;0Sr@!TU}zyLO;Yj?CI@*@bYFL-L$9vWjnWFvS=ThXnzXb^~w9qzj>mpEW&3-uM1 z8(LHwaCjBfpF6;+H!F8rLm?*CpO|L8e8oZ=1$^%$pUgpdcgSIO-?%a z(J%rgHwaNV6l|YS7UU1_QS$9kTmNI-P?v;$ysy;*vL1JgUi@xF;7V3l;RU!QiY$+6 zA>X1oJM7PWl2!64-z5s!anpJk!!*(jMDI$02LOGJb-HbuBx=P_|0tszO-xrzYb1Ue z_sUp`XP1F%!C^1}pCF$rl#L$)*Bnq-*X>K>SO#~#06Ti?IFK{-4)^|m6OLU@Ur;=R zcEM9spsiM9*9PvryMIQqZI1t3QgH%vmJ(8ZMr{=7#GWyd@Yo5thZB+c?ue~N{N~1B zR~--{Tg1ze5~Q?$5%IZcv45s)73l5{RlUUn%ph!cmg!_Q=J>-;bByOw_4g&{bvq?{ zp^>|20>}dsj}+-U7F{+fZ)Od5Nv8s1Hg*lTdD zbyk~q_s+M)eQgb8J(AVqE) zok?i&p}*ENolequA^L=h#A^AXU9Q>AeL!(AydN89FQMNysKoj?%e`bz=d@?pjLZu+ z$=%hV^VjXw4NUCVf4O^Y3Dy6!DE%CKm*0fLf`82WslU(O@j~lzJoWOve1BD~Q4e0Z z{S;o)^H0cRW^zcJ;PP-i)g793KTI_++i`TfUel{=-fCI7Tc0)s z2Ob#S5GQ^g&g`3&Pry}X`+S_q&3x#t6x1~1|2!@7%HexhY&W;bbvnOV@xH(|x1F~5 zx;)k)vyS9kXg_|)+4>%OKLqUfJipY~Sa`la6jaC3X1cz2zp`J*e!o<3^S3!~^lkQ3 zd2n3aq|bduL$`Dv`A|AoK2@#zOm7{)%VlAD6`oDD^mIHr>G_?Up?l)_G2J$?qrHQ} zcYWc*H+%1;f&0DnU%Y(pU*TtKxi%kSliSp6Kjt31{at64VZHG-9l6l^wmLa;;^%2F zvAH=-3zgl%ZvU}9PYzVE!~49Pu={%YV>U)ScX)c6?q+%8>1B95M~h4xs+$ka_Why8&tb5e0u4C46{qtt|6It_gd64t9HF176GPC`#tfS&r z{W&-ywDa>e;fLX6zJ4;+xJO=t?ECl?vv5~89;>WVpS81o{JMj@qeX)6;UN8UZ5Mj= zmAKPp;<)nlNGn%+GRCX7iRQ5z%1ey@{xOxk7LCos3!Ss`FxfCp>g#PgA)LX?c!$zbXIeo~c>9qW_tmQ<8-h3=gXFSHV?Qa6_Rb6*n`BGEw zIm{HrCbb;BS7)56eq+7en`TCqv7*t+yw(%q%XG(XI<+G`;Z#RUccDDDXGGx^6CZ3Z0V_U}H#S0BY~#BouT3`)avR$!?pm#h&Iy7T@>u7-M!mDd#nI68mCmx^TJv(V{|2}D zDsQog6N7gc^{?w!Z{L7Li;uGsHi@wOSx?l$S=HIIk*9sqo+uS_YPgZGy30fiE`at6 zSTiSOs-@Nst@*G~*)Q_0XC+0OZTY_Yhmn4+zD%&XfPUmYego#m-(XL--#5GNKCz}S z(t=n=sLPqsro^{B0L&sRw9vgjZB< zmeLcvD|K58zYxC!ej)VK=uz(s`7!YqXd~en;+xGU!!On&o>Qb(te5vAkyEf!xRbwA zypu;id$WK)i$90IkTd&}-;-Z6w==sl$9|e~s(1P`-!s>HZQfv|Q z?8wZAQ1k=---6*M3Di6;DgZ#{uV9Gre+q`q|H)CA{OW|rD(kXb7EWZwxaq}Xjj%F_>C)zi6F^H_k7?!C?p}Pg&po2)Aw|uf*<}-X-J+h|Y!_RHyH} zdjw@PAh{q(t@3gK2ypHJIu5GT=P%&ix^k=N^sb@8U+vrFi-CC@66E>M7wd(jkl(Kit~ykMRuPxw?RjdG+P8 zLBWi=70=g)9beT&xcZCLqbLF#2R6!?!-fI@VYr40;({3uc?;qL1y(bbw2z8DMPVColAW7&m_RfX8X=)V$2d1g+? z^*+R#96=6C^+FnyhYt!RYS|>dC|?a0p6eD5xDQX|zX!YnIuh^vR0{PYtAGmztr0`< zrur`3j-$sy*nE8)9W-1o<7EGLgn9_lsbSOH`H7=7{V!8}?*5W9YmUJALXeV1QK)8i zgD_~p(XeHY%s)OiV62rJzy0B-L#s|!URmb!wm0oma_Y^+9k{mM+jH74E9k-~T@pe% zI;5DeXE)$SLcUojt+a@gi_U_m!X%n)x$pp!`DR}I6)1$foJGaMcT(x)?vbdiyl5Rx5-SKt#)z-v(U-52!=En4YJTO$@P*0 z{+Ek{bd0NORIUr({y4*}84SfEkJ&c4c@P?yYTWpDOUNt8GjZ(%1DYCMGwb>^=VAuSL!vw#r51m38?OuLqPjL9&EiI8ajn0q%3 z3lh>4LnLJZIZH`|$%f1okW7VOyAv(tO6 z;x)J!!NW)ggmQ_nfbkCOB7zbG!UFiQFGP0hkl&e{DA+t!S1)4l7q0MnB#H?gJEW=f#otw zf;^As?N$Bmu1*LoueCzC8O_0;YZ3@LBU`lC&=O0WiB>hif*>480)rWp;Q>(!xXAkL zv!QngYL^457!c|>i8v2v*EqClR7TtCAWe09{{T`!$h8X$PK^3eyCMh&p?4guh{>B8 z0DT-$2jWj}FW{F^^7mQ2K}wM6E{nL#2%U5&jKEP=iGDOst@Oaj6bP9J@h=`5vPebr z$SOWM7TEC3ABY%}K@q0nUzIYT10L5fqDhiYBvdXJ-sI)|aw@=z@vM?ikvul=U5E-z z@Dx_S;E^)|2X|f?S9*YPBokrj_#=&E-(;U4ekCKcwFmVP0Zfsj7uzb@9xf7UkNa&T zpAdIAN52N>nglp0G?W1M6iA>jhMB&ASzkNOtkPYmsFB0rMC2_RLOsxOS^q_ZzA9wo zHyjE3EnTjgFbBTN;4soF+N;FM`XeTIIb(aL$ z9a&nEm87ysxsvhkLlPuYs)*9ADRti33PE&34L$cek}p_S)CLEO3xi_JgqDeex5cN; zYy0;vy4n;obs9AH50b3T0-@}k#XrJ4G7iuN3tB2BOY?6Y96P*xV>}*MYh_BfeMOwX zp_4KsS}L%^@O#!MNs>hv#MI&-Mp^f%u%o@f>fI2!kY5YR`O$RM=dB5k!l$;d|_Mh^0*_J{=%wdX=6 zOOB^R`mmt+LPC)Ot%9!;^|m#QG1-5H!wW*1RxZR$?Y zY9fdWID7trf90Xx8u%IX7iksuq({Mb4jknUbT5KNJPcQcZxy!`jR!A++C@AhxnxO@ zr%wRkiDrR8Tn2rj1Pkhara)n7Twj@vq)j4|)3q%2v@o`1Noth~(566(WsuGTAf5W2 zJi>FMpfw0l+K)0J<1a&t2rZfor?l#hr%uYyXf0KpGr(X}DcYNMX^MjwGNt)leY=A^ z0X*@d=;U*q0Js={wkibZhi4-hANwB`iD)%T1x|pR<^SqB1A8(`56nuDpa7kk+B=oq zm&eQFgQ#XCYla-Cg^U7+X`zIf%o6tq^xH=jxIbu*iXvDZNB2G#2|UuK#)T;u2xY{p z%7L8*uZcdfvGhqc895JlyIVA?FAj7g?b8|;Z88u!IaAl=A=rkJ-W!Dbsv8pRdXlgJ zNYQ}o<68Q6$p1y!uJBD3R*gP&uE+h6E}yTpb4hrU7@5=qOg{ycpOJb0S-1HMq#5u z0b)b}f(kwp_$?yJdjSicVyBq=ZA(=zLP(m$7082~mW2q3p!yr6Bjm=$mPbQ-p2)&* z3f7_ZN+LARGH;&nOV8I;Ck=%CaMj`QGPzK+`02a+Yp}nthlt$B@MOuf-V-R_ZQqx0m1C&3A zo_Mgm^(c?lj1Dwmg-cOUE7NK+M}!&pY?t?MH?XA1x_ zjN@^U6`i&p0+C&@r>E+p^ddF8`^9!}ma_i)xwLvH;CS z{xL)^KSV#0ovO+pCB`E#nxSqohYnRV$w6OdyqE9e9 zR7ij@4#QBfP z?z?dlALzKUi!EG|c2f-J;n1RuCGH0LpuK%5$3Nk`b$;A&m?mA2BK4-eC#0rquSy@&*UEJ4XxIjhR5oam$Y&%wd>7~q@y*5$P#NAz5TL^sWiWzf^U(Pe=Tq{ z;+>0JjowmMp$=pgeNDI;E~&C$blQAN8@KmPYZGEQvV2{M?jMmia5`3PcJNjXxKCZ5 zn{}wD;C5xaP4zv|Zxg`yS5!U3C)0r)8FIQ?i`LwmexEO?%UixXsR547hNuMYecF1)U%))}>8GWhtp?ymaMz#n@s+`b4Rv}inFk9u_Y?T=1V zf6n~&7H^#VK40&L%;4C3+DbOw>TPc8s%nyE*7rSX4MvI@%kvM>@1Yfu+`b%YJq3rx z7!^W^&qg9q%gp%8x7Xh%(`H_zl1KQg9kWqW9`HY6eV=W&2F%W#v*6PXrke4$a*n~i zKP`mctiHu%49w1}e@W8R?%Tfeb!ICqmor1%p@Cf)-{1Ry&@EJH@TFknirglfT z*}q+uqeu+KG4F7@PO`xH)_&3p1mF8U+h6*iwbCAb9&Gp88XU~rin49TeUEF3-D`m!Cj8!?-Up3Pxpgr(mY#-Fk-b9;dM?j5FtodU)_G-rs8&KM%>xMZ{ixPI&XSvMwsb5$Wgjj>2J>=|cI3RB9=xRZJWbbo z;B`MKQ9NjD);pWYqmrL4o6U;pW-x4NMqRTsU3nH?S_+!UZw%pav#xNQj_FsXgJ^%k zGJpF2<*uCk>{(P8zgfFsd$L>6f9KWl;_qZAVqx#y-8-Y)9&Hj8n^U<^!i)b&I zN2A5#+j?-!X*BJtgs+a$x!h>=E%Gu`Sb*Ql9PxX5j_)RChIu|=PD%e^eI4}a`DnYU z5Ju-hBkR22mS5*PYuPEblk@W#){FINeQcQ6(bLk=d8YcfSwCtg?(U-Q>0x;8#jnBS zC-h~&_5A8D(sJ|hEPc)1nUvw&zJ1onc-xaTK)8Uf28hN=L{ffPbv|a++fy~q#af7W`R?3S~xkAp1QoMjX%EuU9 z6;^k#am$nwu8aaX5{+BVl=Yl@H*35-v6F3PyYs8xZZH%vkwIWtF`ankvaW%D3jda8 z2;h#B6CU$}au&<)>dL;QvW`QDh~V>U6)QmI`V`zOczQ8^{LW=Zc!K1citcG2TJC_X z4a5^3`b>YPa?p4Dw2ck9ypOaNy#8g< zUIaR6Wi0ju9e?&iW%vY7dKDqW0NmlpbP~5vv;e%E{qd`r%>v-A;lCi{#mxQ_JI5^S zN`w><(j^p2MsMc}LU!!p3XLnIJ~`kgF&PQ*cbezT&e0>jmfh~~roZhs#T2i#jfi;X zqY3Z(*VQHcH{T}Qh8~&qXI%nZLwuTKVl?=W$PuzF(>alkN#Hp_km=8JJP{@t_-NB1 zLfhZY#7!YvBKE|ALpDe7H-I;Swn*=wO&LB(K2bgiJ`p~d@0d*~KB;SBe6p8B`gris z)Um)rgL{ZK@_ULmtT(PVvN!a5yF-h6;d_`j#y7Wn{6mfVoI{a&q&HNLv`!&knQtLo z;+{R0%#=@fF?-0&Y+_DgF$Yt+G^wNcHWpi+)G>|LGMo{a{Yq^-vxECKpy}zhR?q6c zR)^_rZ<|22ge^%{2b-Cp4~~4*kr&6FobeYYV67^fme*{yVH>@$PFihVtu~u>tsflW zUSS(ky#2h>ynR!TRY7amEEva_%-A7Z<0RV7F{XcLjV-tI) z|A?y2>KCcVD$Q~(DsFIj@XGD|*m=2FD2BP|e;5fo#oH;9)fyGN{j;1EvtkMpYiXejR+sP{I80!9puUGH&&=nG|i&s)cjT*i)W!Hcc$=c#ka+ zPwUD>orRapu;oNF zf<~KW4vjLn=9OuYDxUd@TwBxfylB@FTra&#MsUi-1T?Tzfuc)lUHFZM;V_&rfXzL;q0w)*BM&G!dLK^X9I3LHWJqW=Npo3 zdxLGmk!6u&UDfg?Gfc%3Gi!?k5-`lwJ4jhmv8XGU&I zx1Z4c-10Fc`53|@6Dal~6m#{na+e~sQ7~T^ z;#ISI1;d4`b5Dw-ni|=eF!i#OEyt_+9`}ry95!;akeB9=*}vC7Dj+rIbj8C2p)!&e z=r7v_4LiEL+ITV6)y6_LXtR`F1K2ZrOoHE};)sb({jGG-Qb6DbbVIPDi-(&>zG5O2 zYJ>>CxdFjH7cd9(yWcY$Flt%PwHU_Vhk?o-PUg8x%{gZ|H!A za~86~&VJ)1o$H)pRu2v&1o1of1jvC$rj7C^R-LA`vS2G04p>0qpOtBpbk^f+o7SOb zEyWUO+N^*g#Tpp_PKo~TvCmYzQ<@c&4!-c8tv-)+qByh5fU`+>2FdWEp>J%15g3bGfbnv`` zNGNbTt!8rzvYvgEB8ky5d(L!??-C{^C2k+@P>|G~p zoow>eI*T`X5I{Z)3WwQPlI?Y;Gfv(lV1sFAmj{Fj1th#B=NkJqXt z9#I;GI%h?Ssm#V_(KN91$Hug*-W*to>1c2DlGT;h>W&jfkf3$wck8GbDJrV1d6SRNhftsqz&gGub91(XW=5y}ZG>ms zJ`k3FxLy}vF>BPQZ3)Q)6AID~_L`9Wroy9bj z7^Ssam{rO%8J#g2z(f|ZrGQ|Q8;2F2AN4m^XXMpk(4L91h(>zQKuz6pvJ<=l{DG2r zI%eT@&@7d>Ya^`I@+VE8yfIv5J8&!IPZI9+?qlhq-iwPq*hbC##NP*wV|)t0ysr+n zp(w$xg(YV?ES1e+Sj>ydTO~5YAVMNG>BKhRM#opeZGb^gXUxaa_l_<2&=$G$RY#4n zapw=2>U=@IRUS8m$6WAf$Kjy#*m3O_*Qs@h6=BWV`E}ztDI?WjOAa8vl#OSOguI6k zRmdFe=T;~B3j0@kOcH?hDAz!XiQiKfB0RIGsISHZPl?tjYW6;*kEr_ZXezZaVg$S< zBlIwR!Mn`xD=W3Q+|L6l6)}UY?Rv=r48`JU1uI=RAC;Jp$yN=Qby?skz3kd;H#y)j z6I}$OKCGtOo6}9ZER8{u*IXYc1fTU=ltM)Ub=e;)$5z2!pdWaPM-Mu4{}IaKByWzz zhQcO7wy;F;tc1=`JEbmuzv*@FWeH2VEMyS2J2kSz7to4vnhTHCm|XyY_g9BKv<@Cw z27WiyF`ym`5UdS&qJ^G2pI9dtNUjM{t?&X$scEj&PZR7kRq|F*Z2=`@%Ot@}u0qnN zlHPL>g!iyES`A8*L2E};T(!LQ0pM76w??+NW<+gP)%0y>D=1y>!Xa*1^|H#aY6IG#wVP0_IqNwQpvlM@5nR=+iA`WGT%(Ddy9}l%1@1Px z718R0ltLLPU<*^0t1-6Y0ug`2za|@R(6rpIceGF_4EZV%z}|Gaq30L7s#YOWOO;v*6AA$1Ww`2qC&~ea@+O z#TncYh>hZ;(9dn2FBet|DeH=Hk$kT%zINLAj5>F$g|hG*C3=tic#$=gn#7^4X^WRjlRt-IUt9K_vv|O*9}F z{u*fYBhWZclhDWx8UUfbYFBhdi#G+VA6LMAV}Eq@!RgG)=WK(}$E)ViCa$}ReYeFV zI4|6|G83KA{m>SKLwB^&xWT7Kzrlv$-UzKd#0j*0Con1uXwh}FC@9S9Qg?SVylCTq zr&`oHVn(14mA9EOZ40s1ZR##DloZ5CI#=#PVZSTHiRf*+62}gB zO|!i(jILPFgVJsLgb`4^s60qQdw9Se18%K4O6xN|<62xl!e7j|LV%MPlpUM6GaNSK z@KN0Er+Q=Fx4jQX6kNgO`p8#|#HLHxMJ5ap1Gi@+JpJciVhJ`{+k_EZ&}R5dBLj(D z?3UZ$@C#n-R&3Rle=E8Hzy7@sRL6!9{4CM)3v4=Bc!4x;7(~h?pndl~etvgUg4{Uf z@ITX1CR4aTwqt(P+3IDpsIripDlzk#i`FOTn2r%6F~VnC{WdoNIb+n2#xVmEeE&=Q zMIQqBD?v-$dSZo`J?!#*`C%jYzwdaRrY2R`p}ENpd{E|${B5afqDdr|at$)p* zRtGd=dXkPq5q3j8fj<%c;obvp9)~7)C4SCQA!^KIiAU{}Fob#^)FvyV8gqM*SmzIO zTPN>u#w?KYIyZAo!&k%;rmM1~tFBsd_SK3VH4<%%8xd$BpNJ_d2V!{ceL;1|Jy(A) z;y)V2)S*5LM8sms{}6Cg_T7c1O)ndMA?Q+SzzJiKz97~XoG8Td!ZC9ajIDiA6iv;k z7$)#zw8iol)`It$+Bgc_8bNu9KZ4pF;CThWK?dVCyg6_=XTtGD3CB`g?xFC*ZQ#gV z_vLV!M@TazO_8|3?$Or+xEOXX7ht{Scs@`su%0z*h_$bHO6F2tr8&S>Z_j}Y^Lwp&Qvzd>GUrwxW9QERaO7Ayb-2K>4Tj3p;ztk_G24K`86t-&F^-T`aP{U189n7f352oshAO~JY` zaLj-u|35%wi&0UUwh8InbfEGwU1cStWHJT9=n~Sx>q|Kp{kSrL9SccL@6^DXG6K+& zJ4s6QJ9W?yjtEi;1;FF+fD9X5!cElOm^-CX5|!Yr`3FvoZ8&ZXEICFxC@Ij@b0%D! z7P#6c&|1s^ycvu(!^{=PM|XD92o3ERp64XJF|1mhf)!WTU2|uf6#^L8a04(5OQ?*w z2eL6Ruqk|X+BC1G>-YGfizk6Mr9vK{QoymoPm5TUJa4*^+Ttm>|Do%hx^z(jCe5;K z+q-Prwr$(SF4r#Gwr$(CZM|jond!OtW_ACCTzL^05&1-wkD7m`v;=I4iMrAF(2}Zr zJw#s1L09bHrju-S@2!P{-;$On_*YD;71i}00M!p{0xI^0DA|UYgtmb~`{Tl&@*t#9ruO6B=5sZ^E-0TnV@TR|^^YQHUQikn_gk0pLk0 zaLBy@kt!kh8GJpBf4uxV`X0TUeNOwlkJ%urcGNv)F64_RA24xx*5uRl)eTph7IaA$ z+B5AUEXr1yr5;sTgfm2^kB^(0Gy&0voJ;&)I>H4z!e07rGyl7@OZ~3LMLwl2(=@~N zq+a|;9a*J+lWn@!8&@zW_>OXRE3%B%B{xqDlzu$YpC{*kFL1 ziIyU@l&6^+iP4YBL9b8@K%zdbQh#qQ5LOa`DVCg#0uXOFWE;+87qHF)rW~hKf7#&oWRd zMXSoTuX@Ad}?A6XTXuKM3fee71{x{ z!vpDyT*68H_Qehd2qni@M*8m>J1E-70vO^|44z7NFq3nN!m8zO&dbMk!45c<|8A+X zLiA=izR}Snc=B%5vB*SgKd#DsuVksLQy!+1Z%Rd=P-h05V=@`yfYZR~IDGou&>ZXE z+}LO+CD*;YtW_;<)k>2KgeK-uU#sXHk2Wec(w*hn0X-tj@WsDxd;#r+-56Fx^MUdf z_g*31-+h37onh^ZNs)8jy*GV0C?SOSxZ}=PASk(TQI%tsSBeaycPqQQ^eSxr-oTUwP$oLcgz?Z#i)DLL%wEj*4(TCf;-gyun zMqTW^9|B$z4VD;;E#+iT9x0hSmjc$i&~)bmL~PQRT_nS3U_yuN$25INdXSU_N^Us?V|5dRt$#*K?wm-`Wzme?^K1ezCY_ zev9iJm|myy@NMK#5>eVG{EO-ZTs5wo-NO4m#%`@atNea8^Be*3n2=O}guDFTLfq8+ zTM6=oK>2!*6hPd;7~RwShWfkC!WdMbjtETGs#sLa=LO2cqDv(cA;3@!jLdXYAc$JkI5dA))MD;LkNfi2D!+89fI<*P+c9A=>rwd+ni* z&g-RM=E4jwH3!*jRj)Ra)K|yXJ5kwxI4*376t)>ePLe+K$)CLcjga!yg!M!dYt5BM zEXH1(mqNS)g69*yQk-WdH3j)gk;KT076N=+fD!{0OcD4d>@Kv?g<0p(({-ia?C0!v z04rA8-iz)g1O_Z5Bq)ju2Sv3{lF$1hpvG2k^p9gt<6=pzZ1#PwNIoa`Q8PA!5WuXh z{M<6;LU+UKjit>|G>B!pkukn4+rB-^#8joF?V+)tKkH)QX}vBZ+H;v+#|M1c>h#UW zro10Yd?eMK=in*cky(@~p~fNra{%4jAG+ktq43Z7wCsNIGMgfW)k}#@fM&f5SG}BI zUu@ri#FW+wZ65{NQA|02+|F~?aBW)Dnk7$o9 zM;6Ij7Tp@vH>k=_Trke*)B-nzKm}kDoFfu<3I&*Gn}f!lV}tqTg8shq(iihj?@o&K ziY%_Ei&iSZ1N$xp$&_ZQL)z`P5?q(K}?CX=ohBCZNy*MUea|0!OM_w} zFcL8khT#P(pg^7Z%R;lg1m+Z&Q^y83>})i&wITS$fGDcQj>H`2$*HXAuO;a9uFHv` z9adLkNlQX@YbI<>wRr{K(o53Zo3irpy0@wwbD|Ntsu57~+_Ja$QMvpfE>cqmTjOBf z(z~F!_;q^^y8UNBsTXkHM{e4^V!7Buo^&f0h*LM75c54i^v+6+K?bj&7h-%k2;aR3Xgo(TC){a54jU636f5{@eaQTr7Sar=cn)n+qMO6D;<$)UiA>JxE8?9qI<{62~(SrFWq!E{B zQ_fkhvr`B6XlZCv*(ocHK86~<2g7;FU}IaBfi++gPlFC|V4ZS2QOeqG5Aqpt0|Ia6GN z1?JpD^i3l!Dq5?pisl*9iDrxacJq)|D20=XL058sGH0&FFJVX(N%o*V}11;*?1SndnKnG8U+=aPFd zb$ueI7#~1ZeB`24$DVuG*GWSQwQrtDl!W|Xg{;XYFSxaa+#_*X5z#i92(ik;{LXB; zjMn;wYC-8}VPgR;4x+UL)9i#k_q)-Bi#nQZ97tH(X%LmCZ6wU$flrD=%tj3b2nij5 zyz<+`-9={u0oznN@neuZcrE=P%Ode2>%Ffne*Miz9e|L!n=?!hRinO|!(;-b=Aqsf zd?%o1`T=Ju9;&JP z!r$w2fiSgO$xd8KYB%v1BSjJn`qdE`UG5GW+QFR;1*N*SljuIfNtm3ec1-6Y7g=D#v7J^!OG0^B`3Ra zIy}VdvlD2=zm3^2=AuTLoSFLkA8?jDgnbvFCq_WHNs$~Ty|FtW!IxA+UtY$8%I~P^ z-}?kxr5nn%W0c65*M+6-QJgT?lxRe{RY}rv@SZ&E;G((BxOI}OU@WSDHnl%vVT=O8 zK(~rDF`JdE*|e!wSIt7BmRfsLjPd7Z>k%B4;B6rLS~arWH>P^R3~sBbld0r=_*73) zC>_&THd~&@ykJzr-o;M;ib*+hOOA?mxl zG(MSDQ60O8hl93}36U3)mrdwS$(rZhO@i=mth|OMk}B`SETtmf@b_gi(w+oD2uZSG z8KpK%}U1 zKu#)10LoUP(3jMQy)&G@Tx#SUg(L1)SLAca+CTCRFwn;tX2aV3J|OPM&tPWO{AlUje-wqpTtp1K5@06>-;tp4HN6w<=pon*6j+!|e`=ClGmxJ5k!NATl`#%M$CSy65_Q`Nbo-Zjs) z+7+Jke{}THO-~`k$q0`Yk&hG!I|cTTj~tP#3(oP+OV0H=BI6L1LD}cOqTxsmU-=JL zwMW3KikYVnHA#D#%L(9GkT1=NOUt0@n<1(zci`oz3GFlX` zq%|yFHF&91@11NnaLHO-n>{72W+j%gva?bCb;;W{S*3bG$(i&!e7s(N_;{@#ZIoO- zZb&n|wzXU%{sXDC$g{Sj+)aJ9C+MEsc8Y0iU^f4u)F1g-uk0jFxnXAdjwK1%ITm>P zNW!i@Q&hiyOx!YY!@jK#r^b;Ue0%mlh-a<()5$q9IuiAt95kVlVp^mBx40~>u*_kQHP3m`lMXlHY2X5M4-J$ZZ+w)Hb0i0A zm((3Fbhy>;F^dX*12cRMvoeTj)heC3Wt7F=ITJJE=Lqh3v21W*vqStQReY`{RxOQw zA%F}+@%U7xB9M^hE!qZ|m99CfI*N7hzkO+-MRHz2|re!}hF%7#G4ailM-w2@6}0U1ZIpyuiSs6FH1~If3-lmg-~^ z$Bn_`+LK?zXX2jd5%m~VWTcIuPYgHROr+3j2&}zL+#BFDm`(a>UzP#zktw({OkDg+ zfEuSwdu=taA!^OdAgn z{Ur{(i7Rk<;1j5S6#()6WnuhXGg#nC{LwkrmAy+^mrNt-`eMY#534?GC%|B4QJH)A#M|C0k-D>L>Mt*J4a#M+}A`;ziWtK>OHI6S$!QTjwA(sh&@#iPJ#FzPyOjXY{c(n_5r@I z1alMbS0&fiUnmC-Cpgp!2>=BtpSskC@kasT6WRFQnOOmnvp>Rx{-$Sy$CW)D6rJkWe;j0HZw$Zan(cgTLF=I`@seYiZ1D{m`P3^O`vp82oq z2W|fr*lYE+OXD~^+3HS9Qf0DXg&wA@L2|}3hG!MAD`y%7hHG!fkS&1u{Q>LZV3-h z4-Tj5s(I&tuGy~tLiV%R7lAQ~KEQZu;@DVE)AiPfiS=Et$M%JVcMG=S+b5bk({a9B?74sS|kF8@8s>W}@NBBV74$I;A zg+l3Vht1XYXIGB~m%T>aiI2Oy&XtEYZl!nEZ%JH_<3;XfTCIROK+c7|ZS8R4*2AIh z-Ff%rIAK%5U`v(D?Ku~mCr!TElC1>Lyd{2Y`{6lXASS@e@3s62Nzmmpy&xbq=j!jc z6$khs|KB!|St2Z_su$r{obIIonRU|jW~%Bh$|!l-sNQ86H7bc&WX6CK_7WV*PD=Bw z&aHHZ_(W&3v{EaYx0?!Dg)1_03CEV*+Gig39seDm8!-L)?mzqb%h%^J`g zMz^QDX!e1mBG>%v{XXZXw1|GU`*nP;m>|DSPMy~MNq1Mz8oKq+9pQ-lKHOAOkw2?& zCp2;So$ljbs$~s7O=+*xwPN%s%ol5UvkNfj{gTw(8*0idt@_>l80Ka=#1VM#6&9?H zO;Rq*Y0Ri^k1?}PQ>=NRkWjnbwYW7{=)w~N$5GkM50X-BI<`DL-lYlIhW~iHegPAc zMs&@rDy8OEyHKX>>Y{ZrlG&5$nyJ(R4}sPrcK&Cfo@zdeu4QMHn4{7@uA|<s>b4)4R`8 z)=uG9Ix><(M;S0*j_A4AbT@sR&N1UO(?IYjrgi(rTm>Ajq&Nc;p}56Hy@`PVUpp_c zp!HDWc5AW4!ymVAna-Bu)ra$|e|K;EA{VI?XXZ&;SfvVA-_Mt$wS%5}uD$CxXEZd` zhecUAK!sZ2Xj=I;WktPr>9%j(vB}#vKrgDa#B=7XR;}VSiF+0v9DyIpsV`U0n|bv( zMBHM(_rZ46uBz`Wvh*6;po*K0$HUuRW|VGg10Pgq3K`_f?Qv@`0sxTD6xv?Zi56B6hR27gsJDV1JXxyk=oNOyAtB$Jb|_%u%3}WKf^%TzP$n zQ)wgGq4)B*JuX#c;x*D*QsoS5kUhDrx>QC}b}x7}4ec@~<3HK?9YE89KD8`Ig{YI( zP2-()KOm6L?X%VyPTdAE#aC*9)pgtPpHcP!*l+UgIWy$<-#P$L*i4z96_a*P;ij!3 zz}4fA`n*cGc=p)o0jEIL>`fDHPsc{=7RK-1G`2<3KT2MqtBWF3vfcKUxm<>*mvne4 zke5A!^IPPrFm-S7EL;9|xIJQ$Slm=&chtO)mrPiQbu3+McZ|~LGkEVtC7NAsaj!aF z+4|Ix#Wdd&+>HO$FESN-ROzp*9N|CY{nh%%*I5%vX-hB>Fil^z-TCpf3xSEcYM|hS zA4Ip5^J7_SA3)2!?do&u>3lX*9qb~Kt8gg6eoQ9LSNBs(v(e;pJNN-x^x(}9o^0>t z&bo8#`l`pdpnb`GEMtAqYw(F-Xj1QF zWNnVHvx|0$UsLPF(?(zWC2{3stLyh>eJJ))m+|dFtz>QIkO7S{=1g2E$z27_OjuQj zOyox=B9A0fR8#VcY>0SxDjh+tJ6ST7G0zh^=@Xg3d_Bt(+2xkv5FE}2Y0hFjK=qPrIC2{H6Byo9YU`-QY*AjzAOQ6bJ7I?+d(JAAwpL1^mi z{2!Lqiv2^p1(#U(g`6Yi6VHs?ZwY{!6$gd@x> z1G`mrEMYt;lG$AI<6lF1FLDCLP?O!zP|0g2mHJ2M z1epAxN@D`b!5ZiR+~uv{7Ch-$A{oZ3xP(r#j;vxlAJq3m=IvT|(f$#HjXIdhWEcc3DyWMH3t=kL)co*UUkUZ?OD%u>>H=4~FtFG2h*LX1Lkz=w8kF$Y^9YE5K|`F9kcG+abcM$Eb)`gL@NVSZ1Rmm!jFa2ZFk*nTBX$lcJ_L(c4oqz9wy zuqG#j*&&GsCSN?vLlWJvDJS&WQMNa@+93-kKKo$}C!XHWE=LCcn9m0!f`KAWxMLw; ziXk+?H@@+G#5dBP;JrYaX%IHW@Qr)EYEaBK=w>0<)L?SWAhz{D?DPxc;D)dWdWza-eDu%6Ujo!ysZ>5QlwW!Y^VV5MnIRcpx4lOwj@Mh#<># z*oJtJig<|610cM=wBtd#;~~E7U~-CZX$LT@B7e4n5ZWPg=D`v7$>I8uV)}WoLY&^9 z@(vihQTS5Si_R98&M%r_zCrn-b0ti?nQBCAmSC+wGsSQhrYvzY<#guFo6+qcckYqA z3m~QQ(d0$omj}5xVf#e*SOrOS{~jpSyI-d> zS+D+gJC@sRZaTPQkL%PEAIiyf-^SSu{xgUy^vx);7;G!CY0F0n`PW|u22BZ&j5pe!C- zbXBk>@2>KO$R7hFu>RQ8&`bQ2dh;=bx2y1^4n$BIofd=6xC<_1X2(sfd^l{(ShBW< zV5d7-^rP^8#mNhB1FX`WJSApPoqv4BHDYP)yK+=!XXU4B;LqSy%z1+xcIIXIv`#1O zl5XTrSSDiXri)PdKS@e-l@&@{yir&Xu>bz^-8G%ew&m9fe!^x;sn%>dg&q1mDwmYt zRGSQ4aa3C`pkKTtT4{=xEp+O`u>x%-sj>)nD>BxUu^t^4Cki{-ex5f$(fH9Msv+Xn zZzM|#h#dUmf*#o!+^knhWk^ksQY2~K&)BFMN25eGj}=aPnSl0o^-n5znh{$|gg~mK zujL=;I5&_^QBDMmr5-~aGbKo2qaiw&n66T;I`ryai2`15NK(9i)cCBW_Qgy%#SH~F z$z1Y`8cFSp#rGns$y0aFf4+bT&;DBKeZ{@e3;CX;BQ=(4u`;QZHh}KOl3bPMM*(WE z<6MbUg?Ft5C;{L$r?3%u^^C{2HA-(2^U%jNY6{~!kCED!&wcgBZ2nQBFy+GDX?>C= zsIATugKCBbln+bStjEDD6bYf{gbOM}d`^os8p9cYWOAS|rwmIr|nnNX3yoEf8~ znyU3hn?F>YF#JI7Sr^%t>KHY0*^kW%=oC#26*?8-pzbX4Wm5A*+E@xJZ-^ zg35~MHbmwP5W%$=O{nlwj9@FP>SEigyhm|1}0{dFF=enel%~G#6|h$tp#z{Jg20#Fd8Y^hKqEQAE_r~7WIe8 z^hN1pg0jc(DaMX$6wcQV5_3WAC)XTE96kbKL}VLX>1V;U2^?S;)Px;tYCw=TeB*_M zEU>SfJbLFp$Fsa3!fDu&ikR89bJ{*na7^K&QiP8RW|#Y?IpWW08x)$=FBLv`gg-o$AOob`Ao*L!H$8dJ#|cmwi{1>r|?HXXYV zfOW?qH-4Q=cChvDkF?nIrTd{GxI#e1RPB^q=DOx6M)1HXH@#oD z@K?ySA3=Q&JN4Npi2|!_pCIYbBosEG^0C@)8xNvoj*V8>$2o+rX%Qnj&$b1 z-E=R0JPLexA4dPUpFJMb{kG`maJ*l6%>SIcH2pe-4CaR_5! z&+V7%^}7c9=htn@XUlTB4w(>FcXj4i%$L&6=ZZ`g3eG66UlJ>A9=X4|pJ&5u_Jls) z)1eIw|GqoWs>SSlf;N2iOVVb~qTu?a*U|PC1lD?`2EQ% zM9&>IxeAY__=JZS^k?)<>iWHKyM^0T$drm`j%TzYM@AvXHzmKIu$kaq6d@o<9v%n6 zChHnc8@F!^zb5~b%ElwY!KRQZOhUsZ_evxedqj86&L%P-rJzn2I!1O*=9MO()Z700 zB_w=x_@C108M4&z3=Rkg?Z1fxg8z$jvi0)*|74S$CbT1(8qRITt?6!7u?QvKF__gj zP*A+A1#<@%_ZZ_}JTQ>LT4q^uZmFb+>G>s6OD`f4Lv_9GdTsE-AbM-+LaJ1ZdIFn+ zhUi-DD422Yd@7RE#;Dud-%cK+%Ir#k@4naGSHiu|Uyh}WE<+`7v4;$~pV3%xI(|u| zC)cRL&L-6k%3=soX)5oPmB!0@G#_7}8khrxd3muc5>X zsfLx`l$1n>iq}s^wWGMiE2&;MO*WWHrv%Bb03(dE%s8e=iHj~Jd%{sJdj_w|;ymbL zN0pkI4*Xe6DQ>9YK$Dw{DIG*1j+%aeQ2N`I-;L8c)lh$}3RUMMIoi@O9xPDJmpqUkt)y!uukPlSI~S-m=&QJ_eS4DUpp0~oCuVZ>n}-Qp5ldi+>`9ghB0vcWT4_ovB>+FuHTrL1dxaS0B?~m z&OGn|e_b~D2j87hs93lak4X}k4b>$~{weMe&T#$pMiSnkQskawla%m+xRM}-h!^>fYz)z{$9q77Oo<1P7#L6uuMZOq31LOFXiq?`=7J_^2KZw-#B;0+*fGZz4G+Ml zHKNWnjHgq^7-nVFb08BPb4f`o5gnr#HgG1fa8Gc-CuSlT$$CWakPqQ6-eLz zVh2*L)sypX^kR~?EwG=XcBJRIywnlst}-*1)kT)nm+ zTfYZXi&G4_KW`BX(8?hRUbnckWUrnHQqD~wk5sHfxmjAkD>tr)&4EYf`9$Q#c`%oe zIWB!z*r+c;z73@S8g%cQ>u;BpO?m(qw4894k%u>vV|))H(% zfrtSI9)RZ{G!9Ck*R-lK+p?mvq(WibOic)bY4U<9h99>im1Sz)fV$y#=ZBv|AcA?J z5AMlnxd!1*x+X6`{m`Dq6+FxUxaKz1_m8KsM<3jB33_3sPtT zK*mL36|Q9)ujAj1VUHj(Y>i3-Wm}$<rHziJ5`UhjqNdd5tw+3==#qHk-1ipJB=oU2^|&d#?dauZCjZJmK&`br9T&fU4_7-2uur<>U#k; z9unDg`<2pRE@Ll!0ZwUT{w_oJic_18Tr}C~Y`4}Ik0lDToptUf`&j~rH34QD7x2Fw z?=>rIdRAF4?Y|F;84SPQ?y%ZiRy&txtpxA+XYZHWw+*li_#aP=#9NJnXW?_a$t|oM zZ!;H!{12O{QwTLCt;Ym=RXv}__%$-AB|U3L6`8+7V?Ojbu^fa~G~DiT`^&=;ItqB) zntkpY4r&2^3>u5NsdQWFU3Od23_N5e9DYBa_2ve*wCgax1L)tb*WHLemB^};NPHO9}N^5i8zt6gUnZFiA_`r4OyM+E^H^29Nk{Vy8y%eog z=Q&T+LPz~992xAm9rlN%%|W>D0jzIY_SPJ>nx0*abdL7%McxrT$^xEd|Dtwn>(u!* zmummJ?((e}epY>~?P8&;znIu!uR>cAB3@DHvGL zclMb4KHr{TuQ_~j^SHLwzt7L}5zejSwAmS&`x89mbU!Z#y6n}F^Q>0?vN!Ka{O*=A zaCOYOoiz;M$6~(NW$`u`Ir;F)T3?`6^+~KPl2r9d&bVuNXQ_>`S1EuLeT+KXqzImB z_K1B{4-B%#Tna3vv8C$64{BoVmG7bpbuYhv=1&hMeHIQcPVh1BK8oGufWRu8I@9%( zD=n!uo{dsvT(n70eN388V-0g&-uLuU%G=}m`j)zW+)r1@w`){e+W&hV%(UFc4)z#E z9krp%5JZk*)29lVSl&03?1=(eJfeozM}(w0x=ET|PX?YW7#>_u6^&KoM2{Ztxevp` zu6bPw48gWoN?d(O-9KDK_yuAc{iCiL>9)IR7+N=|bAk(85S`T(Qj_C?38&buumI-Z z<>ocgF#;alRXy?~hOQ=Od;&vy`^St8ItWqGs`qiznIXf3)lBhL;Vww#L=q}|G_+AT zqX36A(v-I(>;$-SvWW~Dm#^pB8L_+6XMC!el3K!tZ!|!VSBmYr2+|Rc z(hfX(hv={s8P2X2wH@NN4&J#-@kZ^eGfz%VyA5I`BZ?x;a$&7S>4YTPXayfKUeuC*Y9Pw2A}eW zDl1!RJ6GVv_l(uuikW|mUl!#onX^V4de+Co=d5L|YwT7ZB{NK09N9`4{SS(L8;vp= z@?RntdE|Qu=zm}d+Nzdd-w{Ykr1|;zG;%WUMQUPRP5K<-=zqT5cfWQWcDucriZ&j; zArqk<=FCUMU;c5P@(NG8{f))uYOqMFPo2Um9*J{_ zyz;0#RVBf;)gZFG+9E8fVM{6CklNf>n);Thq&$^bkQ&Ub20m4)zZfzbV@3d-x-49y z>`-n!F{@)O#>SXaWSya=FtzlK_{UrB#L`wILt{frg@qGPZ;ijYO#0la)fDAFs;Z2* zv`R#(oy)zlh+ecP8d6=fh^(*MmVg5wnGsMa@XYw16vCRY1A_V0S`i(w+c?5C` zd>^w96SR&InSc{1I!qtDR6AVA0cB4CN&-DBh12CMDGoL!l?KI!q9D?3E1@< zgo(wFaID7+86;{w@Jv(kbY^)?*^yge$yC(6k!aai)}y4vWBO3A#PS1|;FwYJY`y75 zCMna>ohE}(*%iIu*Wj#A81vL^@cOyVKSArTC{2l+aYGHmUQV#k5oCW%UMGu_O={cM zKpGrjjceIp#(S`Zm%y5CbC4MJr;cVnA|W+JO0Bp32E+ zkC}_k4b4@lV%Z??HIa`R==+7%!)TGEJXzei5>n6cUPvVLipRv}VmfqLird8uIUAHP zpu)sXiLyAu;N3e?*Ij@scwH6IuS9tWsYh!)Gi?X3kuagipX9j~@ZL=kJ6;6|2>cW`pCNH@w9 zPPHhU-ZJWTO}PouVjH`$N-{?_?UL{q*|dsrYthPz3>vp`MPHnu*iQ|P`)~%Kl7(H7 zSupzYVHJeLvWX#14Ev_Et^p|l!9sxu23-OX3j)mpMZEcv=1;VN2jGDs0nhaMgXXUY zgsV0!v{Cm>thIr1`)1`XF}yK#0U12mdFQshGx-4Z^!m>ryg7Y*cT+Pc&8#aq=vf8G zK?mqoIV_cdE8dN1+VI7!#k4duGkkWqz8zsb-4EMae){^`@e%ZCxRid`pPT~>zGqMP zY?a%s^LWv{-#&^M6uwIUHhEuwvpd z!tdO_4=%^r474M^I_;GT$+CxmUh|(o0^JH#j$<)a&t>QkhZTKpEr~DrKt+FQ>{*JHov-! z{X$?ar!zr4w(*QFQlzoPvqXqzs4iO)wS_(Erk-EmAn+LvrVAo_x&SJupQERWOM%&V z$>9+0$4M8*{f6Fh!+fmXi~>wty#WXh=rairAFZ$C0xq|Clkc;gpc4Zz*_qFeVX!M< z!)J<&J8eY{fzH)MGgT~Z;GF3Wf4Ub7SZUxVzjsO0>vp)3uLVqp`hOl{v=!;f@_tyK zwkq{+Uw`;M?5frSUVqCF>5n%Of^X)H??T;#iVC|F+5*@!u<{Ne-|@c~f64v-?oHes zj=dB66ADZa9ugi9o&dgB>mCfw;vV7vWA6@+3iq&Iv~>V*f}c9YYe19m{QrM%HT!yj zK8p+p=$Ib}i1hztD4IFjn*7f&)>m`G2UR0gqr>#7^SV)nz9FUL0Jti5c>EtjJ zMk@lulrmvTSxY^hT!|(qXC+AfP@V&tSjt1gVW_yv!XQ2OBG)f0jdw=oC(vtr$`{}V zNKW(0+w0IsG(!oy6H$BJZOYr@dQDak@U!Pd;d;+YVkyhzMqkDtO$drkkUS2M-OFk1dEz5i z?o}f&)L9Vf)6Tio`M{#j)gVaTnk&|_9s*9Rl?YDHQUSZlhT|%miDaN+b%)^kyDqS> zJt@wlmcyquy_)aQUID#j?pBQV`GscCAr|l2e3tcL2IH6oJ$<)pm%%C?S8j+fb?qq> z(;0PYQ7QcMT`S58H0X580RLv)oH{YgZt0%9-N&a@mD*>avqD_ktJUQwncYxPWll-% zMC$p@4U^gkM~Ddr2&7}jD8;>8hUq(@b^g_!?~u6v3RCF;@!+_r7or)}G|PTRI^ z+qP}nwr$%z=bwu|`6e^TzNktnby-=v*1MnOU9DO(Vit@H+u&8ZRMqC=TR6R|^>mU^ z?2|qvSzUDSD_@T$PoTNK*kw_8?kUJ{UftO*IF)S~2XulKX;4_Z0>e)LgRG%6A@p>k zN>xqsvZ}*J0e-BhLZ2elqoo(u_BZ+@OMN6jvs>XYFzr_7{wo9>ox*D6@hD>n3Rdv4 zz;k?ZmaX!lKI1{`RW9J-tn z<2%kMdqQR}+|0m9w@q_ta@iry7Jpdtq*CS9;;G_Ntx$NAe80C`!SVxCPQN-C%ip?D zgT6x<7x$fF(DUVE&t;GH92Nads|t1U(YUruz(yCZ?qvrdAiLJ%cwqpiiKWS;*?WQQ z6m4I%_Vkm**HP-HpmPZ^mEPkSY@nq`;iPEmuYKEAJu%dk>O8OoY;7*H`!Ldim`fO& zvJWx8vFn*Xo*J05S&g>yw{Zn6iD7&*WylH>!-5uFUPEvnVF4-Lc(u;+WL?J5aCdRX zrUkeAgdDL#O+d$m>VpmhF2c=8pb4&Zv5Q0xOj9NPbhJVsa&u_Z3u{H>^FSE43uN58 zyK<`9mGh||$;qk(;Q2*pvSYI-hkA@Zsu67TP~Qw_??R(naUsBT8f|mNI)CAwYGsZb znizFX>r%eptnnl*l}w*960K+OfL$sDQ4|YZ@;qQ9Ct%CGixNk9vOMS+^;w#NAZn*( z4GMG(y}aNwdgdQVlpNp&lr4fgY@r7oCpP8ai{%p*P3DwJ|4tOxluKPc#FWzvf3~ob z;4Nm5OL=w#f!NN4HBEeNM-t7y7{YfmKWZ+1<^FT65aXcorIeMOl&zdsKVL}w~h1Y z^BaIz;{`L&HQAz72X>dXW{!js=32vBA?(qUm8VvV!eN%2p5OHBoh)6wNZb;NnGrI&&r-biW>lf9{T9)orIp!(I{gr^3KKAOGVt1>+@T)ob1Ja@2=T_JWYAxadp2u zvg@#&*UB0sP_71jCB_P!vCWl-8;KA6%$^9EduzQo|V@jYd&BR_4}Z)(fnf?(jXRCL6!fGhR%f=74n zK0xCx)V7qSaJuP;|>tiJCjZT(_oNi8H>-A>p%fU_sRU!-b@&AoRC+ z3~MEPQRC13j^#Nx%rKmqhiFe73a?S0s!f0ttnCO5br&wn!uTDWPxYP6RGk#7t4+qf z+Mh_rQ&tFAmahzmUchl+LMDFX1~=vc{9$5~qc%ryWonBt(Xgm=lAuA+_H@5te1~Ld z4HhExM15;v-0(C>IwNckQRYQelTZ`u8d*oCNCN&Xon&(QAS+@L2j?U?p}CT@KT-}2 z5;TYFZ%$*ZV%FPPW))(Y6)feVCFClDM;lH%f0L z$y(k(o0%uY%+W_etf*VgSL>8+%Qqmb1B0tV(l>|pSvkM5;E<2x##%otulI>FIFR%{S1>rhOTR}w+E^|C|?ndDDF9w@(*S!4t0$7FA! z_D#-$yMBeR*@X)BP2gf&WKYrT8x%1}?1C2>TPPZvkr4B>_o&CRMCsR&>w1nX5^=a9 z1!5v$uSzs38{x4v)ksvuRo#LIrN1qg`5gO{tn~(nZg5W zU_+5P*oZhDHc;u&cDEwDtnm5VxG7_H*7%qWerTY>^P-wrh z#-HLKH>JycBc2}lo%-WsBGK4oXzResGXyw!_e7Xi-|kFTcfnhL@S8i^GU}<71)}GI$$CSn6h>*;LyoCWnVjUXE&N9 z>h+w9V-ngT0|1_Da1OrWn2$ly=CXZYe~B3!IQ_eCgCT5-CKYl8T83ZD<*H1(ZI%Bn zf^(fe7oAZ+8eW zLg*_ZiAS18W+dm89PnP96P7TZ7z!V3g@)Gy1CNgv(jvxA#1%fs1eF<}3dQiD1G_Ul*okRDF~;N} z$!2r`#Hc{Bn+Gbt$daUUvsKo4F4`TH7ENSQDs&=b0jcp#(k2+&lchUaw|2jrAiK9>3_J+3<%L08mn7Ip(I7@;4V)>|eGeVfkcHtsno zO_*A(jZw{LxEGo-bXX=nX)#LtiUov02qXW33%}uV4xujrn(}+Ss6dPc8l5uOyD50@ zHaslR6J_5N+z}^ajv%JsU$DzAw*Xy1b~kY6D(DBt;bTiPSLS>+-9cTpqQGfKjD#=b zoA49B78H`v?~hSs-CKUr54X(t*r*vJ9r))hbY`Q2?iYe4UP@t(HVz{Bk>NRZfGu3z zoBvygS^fb>nkeZVH}l+MaNIwYHd9A3gpP z@td@|rnjmtbx&!G7wCH^=m+XdPvM&NyU4;=@q@bLh0G_h(=MmqeI#c}xP**p7m z$MoFLnAG9lEI>%prSY5={~fk$9k{=y^okie&48`=LId|Tybs7#az#$)TSRP)2;y*U z>;v2guvW$e1?Bx~xl+h_#5f#Q zdY>;JpwA3g7>O}1BN9_2D)TWEyuCphP2pM}UDc^5ta9Vh=cy2VC>~Uo zimn0HS%4_|fCOj&Q4IrVWwqob!jA92DMGEP>gg|x67{Z`>rsZcEEtk>dI262#-v8R z5VbpEquMx4*6~6eze9VkpxT_t3*P4oJ|DW9uo}Gy#Ot+3=7F-!@S3}nM-R0M9EliW z^R4*GiEljowCo#_x3+yeEcxI7Hgm8~eqK;Paw>1iO6n}d;1bt^ao>oMb>`~omW1cA z`R*mo^M-w*wB~I3tGRP|sSB6Pnp`x&gdYt97hpYX!)-o7QI{v@TzykwvayGCfiW&1 z^!8$toX5W|(p{EfC@vaP$`bK~e8E$Tl--mN?)~u zFdjbiM!kW#d_vW|V$HH@eYeLV>+MKG9(k!eXe!6a&pu;6c+$N9i{Pekx?z!mnVvCW87y1?}_;RcN z3v`9=YJ>ApiKOU`p5|>J*ek-({%@II=2BdhOpVhjeX=xAX8fCBt9J4GucZR;`|GU+ z=>@y`nmgV#mVGMIbu_Gbd{2~3?L8hTOsWjqkXEpg*8%}ag!GYM_KnhvwyYVc08-zQ zvZOfFGmIoP)FXObl)`#5{*$Y?slbNQO%dD3&v+Sq%5fYM)-zs;+< zM5UfVmzGKm$U00SU8lv;G-{M;LIvdh+9IV?#hoFm3jEB59&2J|R-4-E9-J-4MC;ON zz(gtN7xLoYxH57GJ$wX!Y@5mqo#eAJ=TiV*(x|;)kRMM#Thmq9!o2yF$voR7nPD4~ zfR>h6Wc6raP8e(QxuFvwBagGkgrC(Mo|FPD1DZ)JsCnZD3X2P1zDZ$TGlwv?BfV!e z4N^HsI^E3DAmK<&eWGn1(;iuLZw9AaksnA_*|cEMIsyS0(7QcCEQ5~kp~v0o{{#(K zf?r{Tl9xX?#)2yOCX!F}NTW*3!C%`aZi6XflODf?sL02?!^sBuqgt0WtB%J)ld3rR zuU+>iu4Qq~zV1urkHFpGSP#OSUY|M|R*F>FG1A}zNWD>@F%y|c-5Rgt1YnZ`2$vaR zpMjOKBVnOC5;K>uL?pjsd<=CP@3RkXB(u|p_qstJG9Cv)Rd8P+X&kvbU9jZ1Bc{Gc z&g5UAamV108Ga$Fpbb?`_OrG|gtkH?)6k4r!D*aWpXE6Y`E?MgUX3c%ZmrqClxfmx zLf9rS7Y=Pr@s*qQhRFkHQ}D~NN~&;wHDl$HB4*KSL?Kv5mMY9=^{GPARY*ycOm zo{w`|mm_qVYV-qnmb)U?d5^PdNEcb5;kvV0Vn}M7Dl0z}2w`j%Csf6mz@%Ra(`1)N zv&4`eka5*Gs}}-?X?`PW0V8SxBtmOIVg8|#Awu*cFWhwnbcQLVvk+@gt$-=k zXyDvUfV=C6-aLCf_4!opjlbgk`sC$8dUb_0+#ALD*mVuSsxD%Zo*-j|<@`wPfVlPP z{(fDzWX|az#Ctgq=IG|}-B=xvcrF9!8|b9CezIJ7t{K3xc5PCeduB&*aA)Lhd|7*5 zc-O7!sH9tW9+%%elcs34y}fP#8(4VYEKRsXHvw7j?sl7S9f>=#ZR2%L>O$^$&Dd)J z;^%4l^_R)#)d}Dfu8tC;kQ1ZMNwEMEV(v~uX3anpClr`Ds%FRBb~=5kJ~V=y(hux# zmLLy;u-pFPp8aPaOgy((TJ8}b9K~#|h#;Kfg+vX>fKB$Yf}Jly$E;ITCpXNYC^V9$JoMU{Cz%~kXm&!c&GGliB|9zYkMP_Z>y+ECK; zB6e}I2tX)ec_BF&+6hn;l>Q7Ogyp6X1%0olAt66tox}(yCBcnM=6v9FSqclZVP28K zEm)`bXjO5KZdyY0eRmWfT|yafF0hOXh8Ab|NYkXr2yRjUJ5J{{?s-nJVy--=*LeCi zcBFZ-b>C7#^!@vP#4mb+z3v7i$o7p8E+5ZOy@H67+qBot)OcTlNs@koSHPVqB~mzS zeg}R+)OA+WJ89_%WGQZ=HPfs_N4e+bEW;desC+O;c>*5rk^!-4cpTC?)!9Yp4}15T z$+@R?CaN7OikZGZdSYL!wMaAhQl6+a#L3ZQQ|@5|2M+#I>52MS|xb-Sg9-gRAxbg*G{&}fGv zbfHqV)6zrh!zGW`omUf1X>iedigCs(r1RFIU_bd<5(kM3h8^{BO$uP(>(Z5iU@6U> zUmqCbA4cavJr*=W7Uc-$yBeYFGYjN5l%;_S_%?~EqJXKI$h`Qkof5dbyTZjs5m?bL zcmvhG##+rIfGtC->ZTB7qdwJMjLPa|z7w^(ut(htlT|7i0Hk>TEyfvhYZnY!6lCfLL@An$PBlRA}r*Oc+uD3bR%3lJm-02jm;0I=)*Qfanr zew@{#Ik7)Cm|sgFku=O1bE49y{sK5-OWH^eKW)XM(aZrftvg&^*%%ho&*o2^3O9bL z-zy)TgG%&NOJ$!*q?6CyyG4K+xL59=)dn#>`UUK7by@5WU-^~Uq$)ru7W51_;!Fid z!i6RwdpD#kABihP8%7JP%L>BO59b{VvjcFVrA2$56Liv5{EVh?eEed`@qqfhK6>_A*WFX*Fd1sBG}+! z6ZD!90dgE0f&wM@kx)5z9OxLdIMBntP&pNV24*{cGV(XTgc?wVv~yS&k)c-bNClK~ z^!+2?u_e$trJR$6l2$@#;06+J+&(eoE)8RxYf-NgJP@J~N%u z4Ev?2kb5JHnpusSwZ+K(Wk`cDd=g{$5*Iz?8gW56=DF2Hd92Txe+|MHb0mIq^YFVG z1)<6vdn4fFW5AFt`4BdRS|!PX?Dz;OZZZQq-9hVBe;D`GmGX(FKF#0wgUCA9aBUH?1 zz3y~e``+Xzwak}K6Ikx}w2XJ18eh~Wj_C}S5Ho>$o?>w@nn z%IEG3zwqOgW)%_wBDYA#e z8MGF|OQt)YtF%=0PM^ogv7VfsYVTQ=hI*4#aI^3DS`{zxd=}zGGt95WV&DK8YK(19 z^VxEUOuxC5M^~9s(e}wf!2uJO+>j2t_u{Ul`9Pdcy<9F1Bz*(xr$klr>&cOSJtk9z z9;UCk(p>6B8(8MnWgyimcJH+5*+Urlt9;IrcQ{v`@o*7xXrz$m)OY>Gd(}OM=donv zi8MB{Ug7RjhoP*bVR6>MrfIB;6voM;#Y!ZULVtKaxZcu44qLtF=sXJ+n$I`;v*3O4 zs$-2t>GbTb8%f1a4wI1W%g627Ks9O$pN*pDbH++@HMtbMjl;AQzBc`b{?k=%qscu! z>}S{X2_z{fGFJ_bVqrbIx8hZ;zhx^o)aCPZPI2s@?(E0K`dO%6GAn13Rhw;9=i&l1 zAnl2lZs~1wB+EASZTFTNCskM3>BAc2X-*LySHkwsbC9RCg;nK7$!XHn)w@iHZv%n1 z@V1bQDLo~==f%5jE+ugYZ!emvrUPTU({I;c#*v@*m`F7B8~Y7OMkZ zm$Q{0-=CKscF))EuaNe@RWPmyL)jh-r&;RTw#j%Ur_%2%@br>^%Iwag)J}v3!fX36 zo!#qVP@TY)QD=;0+7JCpsBqfKBXL?XmFX0&eD~dm;rwKiYG}BLGUd7MMFp??i?$~o z9*EHdjf z4->hygXa0j6(85D88g?;f)r2q!~0D~KJ4a~$sa=U&kslF2*&Pi9BbDvEzaj>*Fm|0 zue(EPHW9p-&+*kB^QRB|*r_%S#O5YnSEh0`r!R1>+HXtQ!E@f)gV1P=1(VB|9CUDQ zjIO#NZ3muHhjS%Y-S-zQ>}kFYA}6_-i?;;{p~v>W{o`6xF700)M;-pPz<92f8tyu) zQeX3Wt)HS_rq?qCJ&IF(WfJF1n3OAFSEEN4oBj4=y*`?%v4{%WbZwEL?@_?Oy&DaqXis z$Bjv^Cp+1bS2VmL?`r(y=T_b$-CU{b8dEcRE+-9+DcRLm+{UI9Tx{za<1;KSsy8K% z^?Tj_u19f|Wu00TeVF9&j(_uRgJwZDgx`1lSQT@&yjAD0Ociq8av_`29*$<3;~tLa zTKqO-fimQdcY(hJ-5pjJ*$+D4m2 zIFsPPBTDS~O1S51rJlRWZFs0^K~V(jD+Hb)W5>QTOiU6wySYsW z;-6k64}u6W&p)I(k~{x6tu~AbvAxpr>EBOhZ2z|X(dTz$!L>NLy!;?5xMec4GnvSH zf+6CU$V$3$fp;J`GAb@6?FdB*b_i@>OjO(|&!TL1mE?@Sqb$#olk~{-*N_;O$VyAj zN!nr~<>3fF{v3Qi6)>CSiNQb zG3Z*;xFT^u?+gz&ps(*uBZ5N!k0>|DU{`mF)C(6HvK`((fUwVc>t~(TxNzQ0%bYjr#{ru8(hT{7sA-bauq?PCF|a zegD`ER5wKJK>LeYH}>&PvEl$MlPWWGglD|{+vFfkuBmqq`yUU@@58W?I?W; z9jIzO_NCq!c|&Iph29wG`h53f+^BLwzzyDJ4g}Z{Uq|!~YTCGN{5$t!+8|Z!yuZTJ zXz5VU!y|{y51i~n(g?}IAq~`S0)IFe`BsG zn5Q5NqSXbL+|Y4pv{^8wn46=8rY()6tjnLI1cAC%G?RNX*N4v{K{*?6Sp*XVHh-n@ z+%=OHPN|u7cfZ|s_3iQ8?S7S6+Gd;UV<4Ihng(*pfWX$j= z2ZMF4GMtHG#fXf^0_$E_X##t7$wCOGbp3TKNkarrNt8$fq)gf?Vb;jx`9f#$+EOpZv#QbG=JEDrV+Q$JG4ynUq3Upd^DW2 zFfsCogmRKGpg1>&E`EjOB+aaOqH%TM=-_DD8TUl-Xh#MpqQX7#esz*~g{$;&H_qxI zocblNwdy4qEmjGk(8j%&q=Fdg7B{M_u-FI=nZo#}hj*6zB_s985@gBzzcj6MIk6_3 z1tuuXb5E?8>56k0;+W7CA#_%KI1(|Ne%v)Ob-Y@lO8w|sWL!|xyyX=2Q(YWf$zUX2 zL<#c)d91u>Y6jXQ?sonaQIr)4QB?m_h$!3w(Ppkba1{x1B85Adc}8tT4teoM5eW(< zNk!@?%JBDQokANE=6x(3STvRTOi3%mFm*;%1SQeNLpSMQsRAO1ISUJt3Js?F%%lJ- zq#ExX>kJ!cvxK8-YOmFeve!?f`HSx8XV@OmT;d$a$_Y1CM1@}(Q(!yRx2jLY`=i|B zcz>~%^-&~58Ks1jsUR6C8LDyV@>}S?pf~kaNbKt^NP0e`e(XGEcixm5FNB&HnvyCL zH9Wl$b?mUKd__6Qr5JkCW)(fV?DBE<{|dX0{Dn& zTe)zC@KK7YbD)uxk_N>F8U)(SbQ-~%5T`4~T!RQR706t~eS87Rn?uua7B*RgHt^}F z**2!lJGQCD2t=wkVI*h7F8)hk{*x2!Ao0o04e^HIyg>WPLJCo2z2*)(o(TN+x_)c-r{UrEei_HCb^7TNFNs+kJNF?k;y@dl*-caih zW`wqItm3_t4dl+pAgdxlUYfqRS0{M%Ja!abat#0RtjAq@>H}Q3s9lo^ z;s?SnM3CbQg#JMg+1VsZa;E5z(Q_IkOim8S(AhPM@zByVq%>5NL_v0d2W1CgyOP{C zM5>qKP0-{P?}{@DGJ@t1qm1$DUt$nKIFo>-o3bZPPPhiLe`u&kZR}Qo)d~xdDyM1_ z-WmC)Qyun2PKaA}()V;4Q)0h)2H=onvY40|zNj7N4Xu1MGDL%RL8 z1Y1c$aE$XW^8VSVQaN!#Q1$|`W0+6FgqHG04o?qpnG22xPRcguvX^GzI_z>P4tS=1 zJ6siYlj!>ggkJrApbO?$X2~v)kON`yu>Eu~&~W|7Au$n0sO(8sj9b#^ry%$#f_T+M z~q84HL5^zm;{>9q#)32-rpTzi&N+0}Xg+y2`#BAgVA<2(y%o&a# zg1GwyCiPoUU}1y70_QD3Q__K?#%WF^2bWc*v2XWCe$fHkOx`Wf+#iBcGY6KFPF^vZ zP)m>}`BTVX$7UWT1-w8bQ?Sug<17W1(mX5(Oqi{^I3ENzm?3F2H9)3;s+*vh2Q6*s z5ac1r2QKKLNtCH<9udg5{ilQD+L}2vK^-oQ(5k5tj7yVElEwre&&I&1(B@$ZG<3w+ zsNL|Fo?uQB0F&S^Jhd4oR6)=V%1ge%m$gWHc-6i+G2-Ph^(z(?fYZ!V)s=JAKBDuS z>IsA-Kg=)e0bna2_%R@_T9K7yGvT4uFq?udieQNV##IEgqOpk#o}!88YQO9jK$2JE zm|%4z#47z8k;u*{k>02-&0zh`0QImV%w|EjP`A9A*%lojv;DZU9~0*&!xWg-^fHuA zK@e#7)H`EVfKI50sZ6q)v7A|Fm%+3zqdn@ts_iWE7yDXJ*H$pia}71&&3CH`Ve=wH zV{1snAup($+?%RWY=cU!XNKG7!;HA*P6Mrr^I{`XwBhb|+9J1i40!>CAZ4pC`PqWhPn0 z&y&3-VR}0b9i4E6!C|by^Pi``z+zIv zmS)_mgq;=}U?TAD8ewT_z6x>&mdkuY(`-kq)vCe*Pe*lzOaG>3KJhjnQv0|p`ZQ|^Uec8`zX-BEh?$@5hE$Xj3O%h!9W#FyskvKSJc60)${@kBXMp;hv9&8|-IJ z&tP5fJfILdV*D}GHcX6k^dfq=j2?})695s8I20lNQqMJZuiR` z?)4w;57tE4d-#)gMzaOVpTCK+e{RPHyC$_4+pcCFzdyLM*^ai)!@?6se3@rg8oHj- z#^nro;ebJHi`q?(aFcPz1{w87!gKCRvZk}5=d)!L*E40JBHYP4r8!bOTRXr{y2*aY zlwP^LVIZRSo->O!D@incD!fzPL?W#**BLTOPm*9 zXJ)z4ImqC=f9)P$l4}Z4#WE`^I%ThUn+}4Rdb|HNJk;ZRe^}1ax?XSSQ~Hkle5U>! z=1|Mwb~Wxl)Q3#Q+I+Sh49J^AK&_TqKus(P^Lk z9HGxiijkwob9*8l-Qk&aUfz8@2wvZ={hjYM)c<(zb#L^TmdQyx;(G1<>b%YU+c21z zNym3Tx56>2SG(H|^6FzbXj}Za`<-XE@4H-d+GAgGFgjk##kcjjo|&DQ(~(HI$=WUI z@wI?=`ze>Q`?^wpD0G(JGtnyNb-jMwdtUt=&Sw94o*vPX*cl(=zV!j+Lidc)_s zSz(Jdt>YoNeP7`4*>dSy^JJX)`!q6Qif3Ds-t9VhRS1s~3U?#X+-D0JpB*H83ec0aK6))sD4eny`uLzI8nRhkpCVZwC(*m&l$%4x$lR+>3Ch~9L@bX zs<);8?Z<8G{aW|##{Vigx!ORz^}6EH^?oXO5qgM-ywdxo`Fa{GKD{W})x5vyR_eJv ze+wV1)ymxo_4U}-*u38DWL9c0y$P&c3DLCWd>rF*=3}@I6uUC56_=sM`3`m6R4i=F zryfqN2-)p$xT0Q^(yQ^cE!*QJk)V=vyz?eoy?k&a;lnpHxtZ6DOuO8%bfD#vdvtUx zZMO-n=c%;`eYmIyZQq#Okipx4Urm2fVaSmFNj}Lrpb4#C(oXGDH+r}`$+^h)-Z5WL z=qxE`SjCZ*p9mryvHN6_Fib>A!{>7x%rECkduZw9dvje_wdr=>?U~6TS>oQby3?ZU z-Tu;uLz0i$ckInFZctJ}d?qliD{j!FsgY$={Xix!uDh2Q!IKk3UQa_Zv}46o8aa?4 zP3g_q^Mj{|iP_Jg)!EO_sqU9B5h&c6BWY!34aEk6jh69uCu{0P={PveS)Hf`* z?>8cM_%}pvptrAgi2fk=aPka4!_lM^P!8eG0pKmYr zp8O5!2jv&?7x9Q5*{z`qES z1OWT*P@_NK0vY!L3c6%IY)DedIEjDC0zOO|%r(kc68~RGN~Wi+XHLZHB_=UXC*4=B z+T`25lu0d&l846~@mXV@V5^M3R;3srm}N`N_i1>`5B5Ci)Mg!v2MMc|DO4$wB9XyH zRI!w);l<62GIGO=iN}A!kZFwy%Z+;EZQj$tj-hkztxSkGB*>ZtnUkYO6=TAUB&A44 zvo*=|mYU6o$~POBYD8v@$Z`rwkN-3m+P9rsF&aL;&pnT8YiO?;fKJz(d#KiGKaI=v zOQcJHm}aF8H=Z}8P$rR5HrzLaSLMW@UZEK6{E3f1h0+vNZ(3d$Hj~bsf*z+~$y<*i zXZrKa8Dn5)vziD>E4d!wMVKNn^d!6l!jHx%ZA^|hmk?}gl6+NvU!_|HPzSk)xR5cH z@Q4F+o$!XDzfy2+CD=Hsq)9_e1Hw=}MInWxDH&MUtnL+2=(ClSGJ!ZDLTM^x;;yN- zkzh}oGUJG~cXEI*4=Ay?km0=Qg7TF1X^F}z@)B-E74J~efHuLslOs)f5QonZy9Fp< zhVF)p#*7T524EzCkt!`9XWkL6Pe#o+LLY420`4{!tTSk~W(nLcUgsexR; zC0LS%0K&DcW+ZBrD2b4xxHNgh;7IWcktuO{q_~I=*kM8lDyXuKvX{vV2u9^lqVh3I z7%q@uSLzHUJ#>}Ka?C=kOtT~Q@LI+A&@$7;|ym~{TvO{Y=)aiA2oHO zK`Fad@k}$vu!1V&^u)e~#ziuwZ!OK!yUBN8#KjXoMDl^kC-+E~(71xrj4=T&Ya=^2 zkpLccH*69rFC-7D`6<~7>4N0JEX$gtbYQ8Q6LHa41|vjw{zF{ z`ESGRBY<9mD$Nt(LW{`19f9`sBo-*4D3cOx$`|3ktCT{pJ2X`4IoAN9#|rWM-7AJW zv1%Qu=t(q#%lT(*)=9a5qUofh)2ZwY#P~dBNzvxEmV5Ngz|F*gr*|w)PZ2Sm&_m#Kq4Fm zt6%E?vG)8dG%EnW4hUSejIc~zzjk~GdSoT<2Iw&htztn7KYC9TxqY$6t4ww$r2)gj zX;hB~Tno4=>OU+sT?iKI{{oUlZkIXnr|g$9#B=%Ny*7c+rc4&KiY$v_$*PL97S zC?Slm7Y#NGg@k;+K`_8A99JL20~J|`u2~bIe_8wqJSfM3;a$t|PA6YgI0(=@7o6NEo*6biT&oZp9ETM4jVe?1E@OwE>#h;6(qOL`SfF9>xke3%-x z3lL|6aEeML$y^(oDsWM~Yom|10w~UMf;59`Oc4}ru6ebXU&$L zhDkLK;|{XISx^=uZb-leK>+8^0cyOKe^b6Nt(^-7lBU`W|ELz>)&qiG=m0-DS$Zw< zsWN8!zIVuFU&PF)2k>WqE3((6%q{>ve-Fc9^CZwGv449RNzop9d zn0}u#YUDSx;vI}UxDw(1GK~$B9lF_vz#`remwY=xAIKo}8xD-b>bnG!=MHGFIeJJn z9E<@W5s|POtSiVHE2obDu&YoL#1aw8(O?}sRMH@{#N4{3IHthFHp8r?iW}+tYMb=v z?(H_QfGBJp#Jqu>>XDrv{K8l^Lj!_4z{LXU0at!)wm22KnWeE=b#4t#G<L;$a#?^MVFhg$=epAK-4A3Fhd9Bvs*80Y~1&;pl#iuwao-UO0o|A7v_ z&1B98UGp1Np2egI#~c(j+_R4PeWjnO7Aw-6CbSZ5oYgm&61Hu)ZML!8@g?mKQ66lH zjMDf&bc1Tq;y&^Z`h8RK(c0f}bVuzeHst^&b)wrAH>^`^QZG3P?+-}^r5&_&fy>#l zl&aMQaGIR@x(~?#qFf5Kp9>d4N|O?iytCQ|SBia$A>r*ql&;V7re2R^s6oMt8D%CGq( zy)UY!@1gc{)bHx+@B1Dwc}`tH~;Z%lWl9tBj-ma-6zrK$nWD=r@z+4{bgzS zYcEpm=RNWcmaEqHD3;vzbLYAjlgpd)VQ^3@TaHH{r<*KAHpudq6Y+EPzIwB!OxIy{ zA|jnB`rOm@<882aJ)v;xJ~1__`!h9!cy!le_wxl?44NMG{WbUJYz4j&PpP2U_9}VP z<#sF0Q+?{o(CYK1eQPInMrXl&+CMa^uF3i6ey-uXIHr>`#_MYf8oa$`V)j4|%;x85 zaqE=6*VBW!`!ld|hIyr1^><xXxnZGsbr7$Ld+_HMRHgf?Q8p?iJRUjDOW&!*OXRK6q1?HL(;Z zOW*C$2YDKO(Yy^zA+W)!9^kidmf-|9P;%`E<}fcc+(1x@p(stl40${%h2pprVayNy8|l+)71rBT3$pVFSs`+!~q&YoGeFCJfFRZ;f#tf}?he zk$^XAZ^6qL{HJPTEq*_^?jwc1YaHxQa*>?~);L%rw$N zJM-^Grr6`&8aE)Dm<&DhBDIpEu9OUOrfc0v7oP1;Etfs=mTT!bv;ntX9#;qCL*OXl z$-wTi>aPadIzN^KvN>Tji8!Y?x`G7!IjJ{^V8~dp5%Rip$T-_LMSFx5=`NWei71j$ zf^;HgLE^O$_`1{$fonqNIM31N5kPw^#u1=H7`HSYAs?C8_~DVn1B!dbR6=gz>Dc3u z$ODjjdKL*EF?{@Idc|*G&fg#4|Li$I)x}Xr5CQ;Xu>k;J|F4y?vyHjafAcd@>Kgy5 z;tbW#v6cD*Lrojf86XK{NFa&}OdrrbkwI<>@J|M+TKgW)TIEWp3%^>{~us4q1q;OsdMx+1}sZ*Wc4D zt8HGUvqx($XDf%Nm3h(Tt4CV*#nZ>{O{CTI$qvj?4N6wdWm_?4Te%v|8dNFS5=~0n ztE}0S3)$Gw)JoNp$YA|`b0etY3+)!8rlV~|y2S(sPb}H)`5y~RGuDV=4+=GhhGY}i zrmn;+ceRTr!hYg&k#Ev~O#Sw?*p}s#H7nOj{Js!bZ6a>gBnLyk#f( z)G1hn|GB@|u>i3Z&frzfL0Q?h?A6-Nt6LT_>$fFFSCc6jF}oZ9iR-W2Qw5mW)pr?VS>}^bHRdZ6UiZZr%pzysYvlq^0P+N@6zoVwkcU10+r6CM@Lw)yh^rc{qrieZNrlJl?vO?ddf1JAkSyY zu@KdKb5ki1k0N0SGbYDdtqn`%K83!3r~2^6G>c^>4FLH!0p*%>yk|``u58rqrakKR z58im=TC>XAU575mTY=4@&7;rE=;h+6P0Og%u>Tx8jv6iJ&Xb1sDy_3>w!RGKN6hAp z>*Y>mT86J+x+b2rx@O2^X~Wu|5dwb!H?opuLREz^~?TT=*GRR*9-x z?uyjBhC{S0V+tO?vw$oo_sJ2tVK7e$DHOcm_2839V{G(&sjS;L$2>5$ixCktOp6)> z!RY<1mOUzYDW+@HVaH5mQXRGcj@-~-BP!H(TMo(P1niI51vkGrnp0oZGRT1dr zVhh&Wqrl_$DIYd1A+g|-%w(Kq{mGof+pOA@hhi!2bx`9;%NnM(zcZ3XbOdh_JRa2t zZQ>D?^kSkJ`=w+VYi&FI-85Jz_;>^!Dnw)MnD$mHqYXJIK)0_#wGBfR>vmDPI zN~Z{-`!5_i>)Ivp*@ke!_tJ4?1h{r2LeaW<0j-LN!vTRIsgeK1);o1+!bM${PuR9? z+qP}nwr$(aux;DQu#sWgQSVpPebGJYFYKGM$3AndIa6HfZLynWgU(r|G*+1w)F$4F zUL!cHKVHjOO6C(orU=ivO*@98J9+X#>w))|;GfM2uZX-E!C1V`D{Xg}`9`H7wsA`Z zknqf`a!63^bj~JU43-ZXaT>Am;XH;*+>IB8Wr-y)-NbYI)HxMlLPH?nO}DL1TpLh! z)>&LjS>oFA2E~+dHBUS{3w>fkerx&|q|OiWkGe_6?Hgswp@12Cv`NK|oq0soQf#5x zX2X2PN-BR^F5Fp7Bto4LN~}~Gp<8)JrIv$RDrQTIflFR4hM`-KoTVU)=bcQy+uX9f zL)2}e^Y-8UV>5GNB#5~aO&|M@%LW0aDs6~U7-!9omO739KZeFs=fzK2-rBdNH)2d$ z$odY$XWReh01En4;Y;g0a{sT1}Ob!o_d86{^@<3#W6E)LC3|= zU&s;V!?6aw?N&zKjB|=z0>h$N-RtTQA~BOO?Gr(Ni3xh*K$}5DRo{l-Fx2P7P%W>| z1m;iAabthM#$#hlAA^VIz1jkzhL;x!3^-NVnywDGB}ukn?#gNN9}4Pxs5^CP*&%1g zykPZ>{f;ng`1h)Q2eI^Cy?+19mp>nPrIg9^mN?W_X7#4qH&?KJ^E+ADCX@XMYj0(T z*)j>|Luo9L-2|GpVCm0$!E)EukXZ(jA=n*dzcxO>e8e)5O&D>Phqpy=AVt``oZF{6*MX*6HYgmc@!^`o3{Fzn-baj z(w3V${7&TETzn0w#0&ExSCBt%b63v4IfHr0+B{#ULT9Z}88bgp?eBdt@P9+Nj?HV+ z%J?aHu}he@C@(j1NuOi^a={k(ur2>7QTUYihk5tc`_$)nmP)S+I!8>|lgmmUb9?8D zoW4iDsMTVhPSN9GHp1Z{TLbZ)HLnbwm&Zzu06r-)YD~2oA}A$}Rt>#IP3f7hANR2{ zCj={MI2Iq^l{Qd9kCw)V&!jk~K^SY;L&Z5G8MP%Ldsl{}4|2{CL-otrL)L(gF>7eF zCE8K)0p3PQehtYf(M@KMIFMDKPgPE)0bV^fT0|K95pzTS79WZqSdfOqC8a?*hCEF1 zMf0sJTunBpY6(-aqm&IFDymTS(i-3gkq|*Nz+31a)uv>4$L^=UKponM#M6aoV*|S6 zk*P7w$H+0rJ zGV-C|QGS%dCxVSa11JSQzZcq79xDZgFr<7zd%utvdecWJd)EcR@@Wj^*?HC_e@Umh z4ILfB;WIYTk`rIm9IqwA zJS}(y$ciF$6+E9a;sFt4fhO0Lo}wiq2--nM_BM?-*^*dGz*=j8bTlX~S66cS6M~0> zCw<#QjB*bc?{I0ZFOo8e5`xr1_0x%`%7VVBStkb`s0#)G4r<9uBxLm-P$4-k()(6e zmuTU<=EvO{MEmr}-ofA62LHaT@O4${cEHn*Ts>KVwj*_ljj{ue<+bgdv5pofKHHEI z1TP@!oA7nndjK?s!>5)R%ao*REZiMagf9IJ%~0BX4fX2(6G!jCZp>LbXk zEn}*%OYr7!48;7BI7bA%hXjp4knRC5A{{ScBTKEC=#<2YA@%3+n9$4P-Vg8w+2waNmE zE{NlcBYmqM8%gSx_asEcfs41UV-D8fzkHu7gyRJtvJ&f_%h8~kvMf2_d1@|<2^WBU z>?Dnh#2SVGq_GH}{iRK~NmLdfXAip>TlN`d1!rbtD*o zCmEg7h{2Znq#Sb$zuMjTxg=OEsXr|`j@-n1-u03h-mm0KA3+u-{orrf!)2l;I)-Xn zLz{ggA#k>psbKuZbm=p^yI152*NJ=6`AAW4XhrPF4_%*mJBj=Op~=9(vlX>ne1m&| zHS8WmF8P`DXWDd_hm>t_ira#87LB#?MHO6m)0CCPv|!`km7fC51_loh%1s=w`GqIMmwcu-3pCEuPA#o>mSQq{a?#l7tTe=x|6U6bl9^NhgTQ>%QA~Vh0`` zTc3&M%)nJFb56(xH@cxaxVcS)@K5?dkHyMvQqv`hJN$UGSK1gs;#k8;MF5huit1I`_9V#DsNnLoj32!_ZZVvFc6YoCt5 zp8|!k87%pE*%d8BD=kp49Ik6;}bmZH81G-E=7W*I5+C^EBD^e1hh>BwK<@te zn>r-e>*&;)YR`Jtvx-e31b1Ql{iIVO{T%h@(M0wMF;iN4)8EV@R{Y&horGZ3zqr@B zE{#Z>3__0%HUlGZ>!FhQVRThLkS$$fUlD(a^q3RLBT%#Wj|8D`{=sB69u z&O>ZS5VNA-0lf~vuD4gJ6>kTM?H}iRfzT}WE36cP2>S#?KDm+w0FMy}UR>H~@7sBz?Mx5TCjN znk)#fBqu){)ZbQnGa9%hnk*2i`K>eN3)WPz9$MT2r#8F;lrZEONNjc0l8gQaXR6;7 z9?uJ(izt31a>MXLOvYjM>>2+vnk;~DqRaI()#QcE<)692mvPV|_zI-4?GlFH#u>ihEN+KHIaj^!CH=6by3k@U_<7XPvyYKFzEyrJl3XB&s6ZGw z?jv>MrYMl1OHB2*a~js0BcW^r1-9V33U_LaV`9y{o=?b6Q^oI%ys)VgE|P-mm+h|r z*s}s$)T!oe3;&ezy8Ujj!I}zHQGA`2!$BF*`xfKRB%IPct59koUB_Vq_ia!%D4SIr znIF$svbR00)#_j)$(y4zF8;U3RAI1Fm(eIW^v>6yhhtwhsZ;2-FW)WKV$HR-xA+;NVY}o#&h{`0E(yFP`O5ZO>b88Ocl!?fdP)z_jBdC0rb~ zmev6HcPWPut=5J?-^H%v<;b_-Ivd4Dn#umqF%85en(OXq4Se=^qW5uhieF5lBh5>C zN84?A`fd5XlT{Bz_nNqO4YFTw?F6IiRw1ISO&!HRjoyi0N8Q4`H}!uX26>3%Z2mn4 zJ#*osQ0u&dWn1h_6v-wt;H&bOgGX<2;0B`(BmJo5G5jd$^0XA^YZ}oA4du(5k{_9Bs< z+K_xfHoBj5HGcDi<%eSK>@IrjKYoMzCEDzhzY-E$Ki=2_A`PF=|Mr?d?14WMl=8lsG#?&9rc455B~743tTXd%3%Lul7P~b8(yUl-Dh>-z{My8 z9Vi4DEdvK*Azo=nY_@N$b))B^_vtLC4NL01LgpVxg?O#Jq0SLE7Fd2Yr@m!={os}1 z&-eqH`yu|Z#TASZj!s2rzWYjkB|UFu`mA$V5paX>s4(4w?F?In`xYraCRscY{3p#| zx+g=jU8Ui`;DFakCOYJV85L@lqTx<>U9~!*^m`3=7I$)Go+Gq2rT1S;b05m2s1sTv0^c3 zrjq!Jky31Sg;3n$$jDnh3X?r%2IgXiXb4R-baXIG$E{O>bS%$B_b6&(!LPucM<2h- z=W3-+yZsJ*s*G7rhZuT`(b8>Chnl*T*ZnK~61yE2 zL;9qUaAr#$M!S_M{nD^dnOJ;sHh@*A=Y-L=gh%d4pxVG&Tzkn}qQ4;6(nRrqw(r`uUm-5{~;DqEuTZ zKPjgzs3cZdhEq?K`t@i6*)&E$5Cv=MZ$m84FHFeM@Pqz{bV;TOC(?>8?5k>H6V&hy z^*uw}AZ{sV^Dax@8j>Sa4EeU0(kgz+ETiSuwVwe2)#;*jc*Q(e5 z&4$uuldje7R)=H2|4%7WvC5RgiPz!}QhOwR9$L6+ua5mP&s<0LH+jw4>vF&v{I z-jE9-L(P!i9z`+G1cK}=G&`8S))?4BROpSZ2qU2cfdqAfE2-ZS#kJpuvdw^1N@L4F zKdi62x)cWqzh+I`C7D6u*;;lE3MxYELYS11`suvU$B^N9A1%}+>Eg9Qo-OEsarR@B zS_fqp?kgB}~yQEg-xInmWhC$>RA+XYWa(v|4__4?2<{< z^EUYlaBWE8ie;+)dWN`y5N52MYP_FOV*WA`gWaJQrW54D`_$PjVZ}4|x*Ec!rj-WY z-ru_~FiX!LU{>CMy6u9~Z_dpLUQmg=C+Ydm`a<+gAL^=OTNIs;AtOb^xSz9DVH-uv zGDS-`=wf9ctgpPv;260l&@gO8OQR=^Uk5PHJ|&?1!X@F#V)nOgMYKust`KRuiVo~= zoxb>CyhBWQik^^k=N;p)OrFS2>QQa%FEVQIN*9nu6T%a4yWlwY5KTtZ{`P_87eYr} z+k7`j2!Z4zI0ZF>|9a;s0$BjOoJfI~9zZRCI{?)Fe>;ICz<%bYsKE#LzeYv8t#Bvn zfSC6duojiOb}R>kJL5;?I*BWTW7a;R~E|5Ojb64%n!%PnHiQ*dGmcq})8pmHrndyiGR z(-h-BLVZa@q+?D$?D}QaJ{k!oX_%W3SM3>Yx1(fLu2C6n`SNB z(8b}6@!~%E8$f>43}{Bg|Qmb-NqIBB=1(fV5p6i*B* zO_7W*`VUP4BnF6I{IQOn+Clf{o-7rtCOM7g$)6_YLGkkIWZ*c>*A8|v!B1IxkJLO> z8Gn6j@$)yPv%cAV*ta|w`(bDkX1TXEeqD0EYuLBinLe@F^36Zd&FfFEp0{g$QI;A0 zUHP?a^oNc%MmN8%n13pp8w{@Q)ij5mGgx@pzwAwa{hD^#Jlr}=hUh}^4cOdw92R!~ zX>AJ5LT1F0#ly9#a60(?`BLkU@iRcO+MGS$_25~J-B?(5X8)ESEm2pK0%F*;I@ZM@ znVa7f>~Rx0)x+w2JTLii@oS%ZtkrF`xU2W$Sa~Sm^l!SDQGPt6vEeE6v9J5Rcb$7c z;Q3GJM_mw`x;heWQ59!}5i?(leWyQj4D}kgO<>A%QN3&ue+>zPuO%wLAq*B9D4Ct|7Yw z+&&+-`PsSQ=!%Vs0pn@Qk$k;r{l%lYK6u-qzhn7j=e1trJ(PQXn`zAEsB)tYY_FU) zTV1(Wzn|Pmd#CX*%Ecn3+(kI@^P8Vmx@>$#HWw%_dEHn36p-JI16{7)fKzwxZQRgGV+EJXd)%*5Txa&;YKzS@uT-gkvq4iov*Rq^(wN)U*0h6}Imtv8>wCGt2&I9eU@*|(3o z^c^#a1klzjuAg3g-JU5;i*x++U4E|Dm7(yjXn}VUvWv>{diJt8n&)Z^^!R)>f4AW! zU7{ZUBr4~i5}W>xVUOjP)!FOO9eVd2cd4y0|S#HhcTiN*eiN^W< zg4udIi)ZKxPVNSj=vgXTrwY6Kv)kAD9FM_+<2@*&5P?g#j+WsDzk*$vjt$ReI+X!= ztH+DC>@!P(%a*D-9^QHSDOzhc3OB`W_S+VD+!O4jbA7}4N+*7jpPl}-42ag#)f#@h z7e-Q}aSVp&U3w1IH?x+4LezHMG26k8x*z$`<|u z3p=^q)W@0*H?z~OxN(s!&}~_EK1ZAuK2bg9Q~TJSinF&vw)y@~=i#pF`R#tb7P}jZ zD)7I2b*?Ms^<#rHy!I6~j<;YOmvykUY&%o_+)=-y-Dc3fvCYb7Sj>(u4(&~Qf0^ZP z+1X;3n>{j}yz{HE%J~ivc}nU55LyD3psGwippJp}5rKZOzt7?VD*0|^0$a0R4ghzi z9|%K=qm11%m#N*dD~l=o7o0}{`1Ki1y-V`3^K5^!UMGf22YA~bv>A(UoNouNBZ2}$af^YFTGxra^@A$aVd56qA|A2mD_Yb|F;Ei(^=%Xk9g&-&IjJMSD zWefhJr@5qIUuPgK*_2(oCCywDOv-W(B9zyUxzvd_NO11--9dhHuM&?oPzum%H9W_&8?F$+N@bxQCR8Qx-utcBdLF$o^-9hG}=~hF_UW$ zq*+fbv>%Y0Ytvz6@=FJDNn^2w#S&#Zavpx<9;+()UDVz4$!J(IutiZQvT9dpZH(>x z#l@3b6S+Cf{+(vguCmIT$+wv*!#GGC<=kv~$(lx_Sut^|Gy8YSb6 zfBGeKg2Y118f%4Jf(Sno35ksg3Lhv$6lqT3WF=-#g1us)j1wuL^Xe+B+vx)Td30V# zw0v2jB4;GkCD=}dKLu`P!vIz|!iCd|(+jDPOS70{Eax7){`)SBENz`}oc%}sVz(u7 zyT;chnkx1XyiqE+ap&gu8dQ`_Z~%1Oe>k}_Iic)^hsnXEV=2`WnodrFjRBDzoPaS_3ih+15r zn9LGOJ6^pQ&64c{t5&SPP`L%)PSnhjqe_sy1r<+F?ToNWJVFVMJLp1@k2_+n1m=vm zE4HpM=M23o?xxtM0*FsIVNvA?l+75P$H?L;P{$DADr#%reI3VR0MCiyDuO9~WRVje zVHnDjRDNWV6Dr4v8b74jk-hCuS2ys{iRcGaVI<`al@~7{s((me|36_5{owSy!hc!f zFpVQOPn6y8_9JKAn1lmv-2{aLm^b3S=-+|0dpci?z43&5m@njhVq7OeU?);}QPRkc zM08P+?MNOgiA@xSLy;#_!YJ~_V-jSA@T7xd6XsyjWF^ux($il)>3J?5IgrQF)Ad)!6Wch#C zc0*ndp?e544y=1nZU=1c7(D6l!z7L{abrG@fX?8{zXRO!kA7hOzXZk^k-a!53;^)- zADc}0eagwCMW z@+UXD#jCgN$+a>&e$dp4xOR5JTS|HMLd%Dk>ar_YJ3YautKF=8JxW%#Ii!eKK{n0Y zO-@d($!E!WioF>liIB=m-06?0-i{5t462-r&GezP@?sjM)(CR-Qctm}RB2jjA8++^ zC1+uD)+#3fb5_2op!D&5OIiJHdFB3qteV^i`4ZJYnT3fHTaqHHz8uN|6CWOqhDwt= zKzG7vd9$&lp%@a3_OCIy!1Rm49~Ov*Bjo{sN(C;-WG}dC8?I7PB8p~c?2Kk}c}wwp z^+=G2>^Q3_Q+g^Jc(SxvtFm;mA8EB4}e2IhCvIWT`2XsirJfUI}I? zvLzaFG(L6L+Xs5FSFqkF-Koo0dXBW1_PHTD=i;9ne*=JO@LCODY=$e}d55slS^EMF zZ`v=5pnFJ7p;t&d*QKX6?U7fM5!|A@Qj$`cNh(q|mh@c$bl#9<8tXRquFNM{I+X=n zKc542BQFOf6R;&&5L@_Fv1M#f-B^l=xsX?Cc`WQUhbKHsv%GX6nT!`=Dl)@EZ>(Hm zF{%k}dyN0v0U6a4%(4AM38Ruyw%J4zk;wMsg2~uD9&8@d*#2u_QqbPfm{rd50qXg3 z5d~HQ+8K*kF{C2tm{~57m##54y_T15FfY9jem{0VUOotJO6oCkd~_<41;%)d;A3(O zl?T=%pxz+*1MH|+Z{`kpZ+dgPH#R3zMk$I39dbJicpD7(b(yRKBaQ{&F{lZMjO0MP z`!7jqrK*2|F|8%#C?(q)GzG<97kmzwBsr!A5NiNoa-DLX7AL7xS->8*JVFH71)38A zje#PVn0RZ60~{8K6uTku-^c>TKta?1#gH0cebo{i-Wq}D`Mm#j4VeIC7nU2CS zm8DS%6LjGC7oiT426zHCzj_XZ1fTRg@ETCNtu_QATsK zMQWY^-k}v?@9LOk9Xd{Hb|;#h_?4dHTQ?9?jAddj>%!6a|9(AiZ2(Kw-L9L0Hi&NF z#Y%KF#^zQn$k@f8*ceqU)FW!AIZ(CXilAHAAhlq$Zj9aTT&$Q!z{0Sko9~^%Myng| z?~te9k~d_M{&RBF7j?D~pm(j+fiCQu?8QOHy^lj5VTrV$XV-?e51{dq-IS z;NLT#5NW~^(j^YoR!ulO2wPGB^<~jYbKMeow__bDj{M*f>cBi4ZoimmWJL$74gzNA z1stR{0&q!Wz8v6s9$tL1b+)7GcWB_qa@iTj zs$w}DXJ9|f<=8dpdhvb1{v?PP?41&n4djMW_#)oHC<>c{w1e0MVD z3y-iSU1HvVJRptO4OUgIvoA4FRo*<_^bn*LDBj2Xi%GgRBuV0h?CXwyf1K-*b&C72 zC8jD*&+BY|_$BMQJ8VZ}cRar~zl{Q9oGO4jnG^wBGr{K7LGwUC1f4oq$ufj!uTxkW zvJWF42w#?Rz%9!t1Xva>AvB6$^Wh5k(gk(bmUS04n3az~)gx4b`Hi?G%myEW;_hyW=$ zXi+lANElt=2FQ!310q=DF*+9`yS+CSco$UDvJk$ZD$)^2k~UdkW>_qAV`veXp5{vJ zp+Ptgv1I9CQnY9|YjU)>Yo;P+_H@&Dw2hVzQxUW{Dg81~ISFqAswMf-e4^m2U63d7 z5>3(4dB?htrjRWp5VH-8+G98Yg*pUuok$0QR8_2mJ_I;Loin_PjKV|_gtw|pNkJb5 zrX7j)Bs9|6@-IxJVHsYRUw0PP#vkxx^kwH9t1JYzNw_CTMa=q$811mA;Bdh$qnV%_ z#*TBE5>XR+ht}n$O{*EC5}G(K#%MtF4`aK{{Xo_{!B-eX-+LkHDZ(_PJihuZw39}% zi`hV;p%(-#0j$gLXhb{I+I(E1I6+YSoukMCn#Q6fWq=?Ya9wo`JL4Wh^bSHq2hgGa zNTNG4EL*Y7F<$sZ&g4MaF6^*2B6w))uFF1=3=twWXb7jEEuk4ttm_I|<8bPW$FEm2xT1Tyf#b`NiS{6oxPCH^R&tga5(-e&xhUZbga$-lqy2iJy zPo(uH#f|k7<$FyOAAzL~Ku}uik~M9_@)PT;-35-4dM33tttahTCJ$?H$`cZyg0I#6dBpJw#{b@Ma7+_%!+ZauU_h^d-?8Fm2@1FEk>YBB09Q?sd8FAA8-$$==j(Y5VcuHXiVrbiXN(!0Q%E!}WAevYRqFS=467gY$bo zqeD=B(|>a^Uhq%AyX^W9PNks0o6Gez>5{LUmq5Lj>vf~~RXvV`E|~!^>nk&*QnWn8QarwdDtP~V{X3f z=GW)h>|&D{q^m)IPv`=r{Y55X^p{X_1p76h(tflRTALkNGNqKFw`&(0MX$tcd7<rMrCH#cB)6}{x6Qg9@p2848sloZ%8M_X_&$0>(%+W44EOlH0gxY1EBiHTQQk1l=6 z)+}k$c`kdAtjcxYA}#F`Sy`%+*s>qWozUqt^j~|KP_GB}+ac`-K)jLt@%5u?`}Iax z2?y18jQE34HHWNo`?RZ0@B{-K`~Q{a^kD@M?1ejwj^ACs(fd;LVf;ewMJOCZ+?Bi` zePRB9`6CO&6O0H9&L3dhKfclWL-h-){no=)1pNOPW?(#1u2*~jpoSR$!2Q2%&=zK{ z4vzl^V)oVY@%*nXXU&uJQ~QjYBmwtyHWZ1JFh-U*Oi~_rEgkJ%R@8JCK__Xf4OvH- zlnWtxFcEN|CE_VpWaru1echHbE8JdM|CE$|4J=2Mz)u-^{czoH+vm{#?Ga!h-t>>$ zs&78KGr?ulEeJOy*1U{>k4Duvq-zTEiRSXoSoyOvAi`q?cUa@#f6Mjv{`Y)kVpVDCQR9hQU~igpHj6t?C?x+ zbem7BA~UWr{#`{!xTr1Z-nP~peak)TQv!OlXD^6XKe&OV(yu9#gUR$nBbSLiH7rXB zHfeFr+N(z~XRY;EHmbO@UR>lx+idB|b*$Q?RJxXbkVUyd)y6)%?P+FF%PDOD9&M53 zv=vo9lP*K<3B=Lexra#AF2V)nWCXss*!;2CX;Y^nE@{1qs7o{N}2N)oZ7UxeMMWpZQF|U%Q6eI z{?zKWmSc^ZL{Vn#)v0Jc5$qNT40bIyxL#eq$dpLMf{Q9r2{%aRZs;?F1`C@XK%q9|{n{!`7xrqbWrR1hwzHVzSo%fYlTZ@pBbgCZC1Pnz# zo_rgQJ)Px9@2)-Ff(u0Rk#fhhDh`84H-!va#0%a@A9EUAa|gsG%_-8|hmTC z=|+%iuH|&v7zIVc-xI~u`^&_fntTqWDTTvcMO-Snh9kx`egWU`PaEQcd)>RaR-4uE zweWd9d&6x=2Dtg@?QAzWlj)&H6aj^ME^xd_Fr#jDk*x_+r0W;wQq?w?c8sgqHBmSB zrCh_}R1Up573_*>2U&@zGFIn3f+;O< z-%T>t8EAYh`g#}!^{;hnt^PZu&{`PwT4(mtjy4>jtJ9YYSE{O$g#<=X>2v;a(hibS zILX!#WpQA#MP0QmI#32ArfH^XuN5*KYW-W-_RG3qg5_n>!#p6u|Fu!urs;6gWV7}f zEhPnj4D`%XR^j`LkK@{G*53VYePy$Tgu9BioC!xqq61_Exl-pkmJ4{K6K-Hbkhqb!&;^pt_>vYb$P;wxob*cDQ&y2M6=cedb>*JOm^(3FEk2l6 zK!|SY+aeaZ7d-awXo%`??GYq?U(pKG#VJMU4e{J;zQ8XnaYmIefVPzQ93_<&%CV*z zn#5F8Zc=;1QdBOLslhH`l4K$^oNLYe`$kZ$aSO%kN51+FniNBbi-|QANscQf;38)V z-Ehs9oOY>R9|Tq6Jq7(3=0Lc;pIb0h!{}oQZxB8pYE$e(_RRBgA1H^e6CwlUwJ;?k zE3Tvh_-PyEA*ajHX47y-GI@xDAH!G9AfO726^9fy=<}QOYABZM^H#Xf8{!S@nEguTGTan=zI#3~4X&<_WqPO$s2guM4N%WV3ru|WEWax z7B8X-ly#7{VJ_OQya`9qohydkZOKw3&9Rr@o=zj(|8vG(bbp=3?o!iPMzWN~a%Lto z%?y)IlP#C3zsS_zWW>v~@Xjm)#a*7>Co!W17U;4?IQ_b?exXqdcju6D=bFj@*-eXl zfR3RP&Fr2==GoJr|J)Iti^-*B21)|N6$=v}UKEaYHM)Br>V~jn%N5|_Rz({MgEA9i z6P>`G5i|Idy^AfBM)lCIR;gmG6Z61g2r8E|BHpw18n6=+^)Vmnp&oYKsI$^l3PZ38 z!L^)3i7B=$;pbnD<8q0V4Ey4RGn^d=y|;|GW)dxdBB2+jYRG{_s*Ed3z8ROvn%sn; z>i}zDD9Bt9?>)6BJ_-}G2wfaIq18c%l2alpAz>kU&l=0v9ajhXvJtHXZVx1D)q;D! zk#%_>ah-#oeGw7Sw!vPSML4DdFCo@2fDtvS@qHN!cVbgR{Tp?m3~8p!03j>XTf%(g zh^uuR6GrDDz^4`Z@viWlw5}dxNYh+5#(u^@?q(f>YgLFN750_;ooSFlTN!P{}oh~o#sz-X!6-$Xwjj3tV2vg`nrT);xX^?Y1YOu+{cjfVFq1*Zs zt3+0&I&TV{Jn2Dl&*$scFlsDRF99_aMrb_{JIIj2G4<7C@02akGyUcrC1&g^(!fAj zZ6bt^R;6#j=v)U*>rV8?S{l28rBYj3-rSt)kUaiv=cgiIK;UeCSylDc@RYSd!UNpL zQjJ|U@dMNEmGC8J*QpIg%%t3f%LUDI|YO(<$K6$^u`SUk4r zk$C>ZtTiR0W0YRJCOyQomskUB7p-&Es!z%oht3@e&Ty^_Q$f{_W!Y~9gl#0MxOJ&) z7f9=PTTW>P=Dl!KnEm-fs5fY=Sm`3hyt&sB{3#?(jHMgWC_`AKnj6MxId+77i>2i2 z0b6cBHr514XezHn%PfDWX4>e#j>7KECqia~h&Qw*4=gvh3rGh!T+w5AeCBXE^fEgm zdgl-qwBKk%4EtMXW&cEFma_S)15k*?)V>4S7aya* zm8gEsBAe5`AwoYl&`lkP2MRTFs76HJ8nRzK*@r&Vhdx~+jmcLRxL-Z685Ey!DgKC8 zu-M$>Zs6?h0Im-SypP4eN_Awf4$f6+eznLKHbsLwJ#cep6ajC@15WO~eX}O)pkCB97v2$8r@|_UQy<=GzruV)3gocTd-@@jX>SrqZ`4?^U6u@0P_Lvr?ZNdbydbsM2{D9bTJ# z`?F{^u^08d^QfLyG$wqadqg4dW;=#HjI+3L(HR2qp(BT za$if37$-~%Qv!u51Bg;r3(b!TX7S?GJOGAOg1(^ z3jiA`IedsG8hHRtRBEU*nR1cTBTOw^W*;8}lWoRpnAhf@HkD1-wi=lYR8=bD!F zVu(!6jR*>|p?ld_2S60Mrsvd$g6N(PMf6XQ5-Btp&IlJV8W|_y9?FAYF3O1?Xc6j@ zF?6b?kXhkuy{QhgTx^8F-tZV#v^;)ZwmV&(H(C@HSm7Bb-hZk+mv1~Vm@ltf_ zJ#yQJ_>1h0^qG54b{aj}R`LrJvL|wK+lVo|Q~utI+>Il%lh66Drpbpfjnl9G&OUG# zHgEjkzGW2rKohq9_4)4e-`|#R9+O}E#(;#){&A77z+B*&Poof2e9rmdFXs!?UX#~O zAZ_oWe?j;^g}EO?KW5R7cRUI5r$ym!BA%e6FNS(6BJtF#VsRqq-AG;R#D5XS-$@{! zQJRbVHH{N6Er-`Ax+0J^C6I2$5pTxHUMRn8)!v$seP+CTw2TvY91K#{QQTDio1WZ4 zAJnGB;g^(UfVVnN)!lz%TKH+1T_`s^Xc){k*cdxo;LGMN*XOM8rzaF4V-C3PDzfM&N(J@^t=DXwibL$nw7qRV~s4mItaJo=c zz|xDO++=tC;{DNQ+{jb-3Ek6&c*IbgT+OM_U(pufB<;ojv?hMEP5#i?At!juUK4U}_M5@9@{mAn1zvhuV}Z+~>{4nn%97 zp4%Joa}AeoFY+M++q=)I(dg`4;_g?-6NMXoVlR1JK$}*km$GP&`K{fpz#MXASBa#_ z<-Bbj9(C44&Z7}8a@!#nN0;TteP*PXW?T}zG+iYX;?}l-SDd2NZsUQj6I-J$) z3|mS~AgD^<@+KuMdxG_($7p#8VQAB7&KV!XL+ZMx(*tp)~ z4^k~qQ-<-5Vr-lP?yFOb-1fDSCcvj0_BGmGWer$4Yrkl-XP!2;0_1Qkp_CW-uVH>>sO2EjCSPfxJ$vl_Uw{E?w=^G>c;2jfn& z>fv#J@{MDTO?@z}Ec<77iQ-@H3J%CaRm7N=FmnZtEQ-VM1vuWKL?ej3-x$v3>NfWX zH~8$JFV*9hH89&SopU5LOB|SHwXb}Ciz9xS4<(l((tYeERZdgCbnXo{$s9M+vF($s zvz>vR90`A_pbq`y!qZt{ciioB`!5dq?T5Vj>EgRSJ^uZwPuAPDK>U}0X=lGHP&EAA zF@{K*xJ;bbBRpSE-c4T*(7Xb=5G~%j0dy)VMn3JIhG?o&9DU)De&uyCB<@EMTs{!N z_7R-k8sF)4`lFWIx<^zXF9a9)#P~|OXk8h#BkjgQsIX>?>;@TY$KDD<@CDd3N*D&v zp#Pi1{LQ;U5if{MBi(9^OJ6L}6c4bh%1bEv#_$pjoSDukvg4LTCa#c}4dDHf#f$`DFSDilqi(1mfv7a8C_@ z{6~;4^8Ts#Bb55<-}it(Br_$@v<{nEj`Sli@-DIPxcKFUdKmEc{P39~vAFS8Kq^Y? zTCZxUJG~8Nvg`wDKVeQ+%&@nW@W99i>ziuiSGHOa@=4UZ`?m(Sod=tiSibdjUn0Ze z)YrDL9B}U~_$8AY02@hwA_{^ShJRX6(fhW17Gob9P`o@o6DjgNJTdtTI3XV3)&14a zF`ho|OwZZP65kC7HXU3qNB6-VYa_9YyewyYsjP9sY(8~~;d5!1XaGc~%XU}Dg+IBMe>Sz8RHJWW> z7jt{`uiBg&q;6Y5!2|4kg=%^p$H$E1uM!b+)#E4-2;o4$_}l5r`-t&s>UbuUsM)F9 zgnt8zwSyNb;`GKtpRmCZNb?k9G(UDRZ=dR(Eo@A0pk3YC``AqS^rWF*?{Zm&F-=2! z-2V$XtHF4puAt>_WRbp(?Qoi+6C)ZXvHQ`7w=F*S@)Q9=2%y#sSoZr_)}^}7A| zG0){9j<(pXCEXmuUMFp%U*0CEUShq$oNG4w8Wh7m35`|HN`pidEiQ?qrA(s4s+`t@ z*5Iqqh)v9{>qr#&b6TuZE=}ycCzivvk>$dM#)F-z+v29Coq&e>hgw_V&te-Ln`LX2RCUR2IJitz>)%8)u@XXw$z)TS zvv%Nj`pxvBBBQWAljObR6`=>h{uq0R#k;7!BVz8d%pp{{Xz${t$asx6{v_(47Hp}z zHOc4}@kZSiK9R-!-!v=ehiOFp7|9<1OhLVNlU>*!R>>jcMG2z42~!FZ6GNPf0p`;OzVV0Qt)?~Td67sWh4uf82WGf#PepWWt^loFy8Q+^Z& zEhzGx#N1N z*ntlbetY1AellRT-F@Tii?4Z+eQ-&x6)=VGbIGdcQw*g-l!0Dl)RMehI!^hwwDh1; z6u|TVZAnq2yw+gFn!-|WS{=D|NMyIc>MTV8nK1Kjurk?7LMvr5#7o&kH*jw&FruhW zX2IopZRLSvFIGKRl!RJKxE1#jR4Z6eWKTB)N#a2OXi_pT)$yk^G*Z^TtKyv+g03sI z8JD*kh3lQ~sNHj`M1&_91&_siDD)* zSsVt?G;uMTI(u6+lG;H-WLtBjdudJvSzo9}>KsoOTFON*#bOxIZ{T_>EoFXEsK8o) zs;NU0v6f;|4S~k-pr{z|73E;8v=!nAsvE;&y(N06BFRhVI{yiKk~Q-@?cLm+-dS-3 zKm$ckeP{$>xCk8bzFLj?o+23sbh5ITpHj97WF@FjPqZoI4SE`0(-ZB9AM%J(I~Y?$ zlrIM?&?>T+w*nlC>Oz-j01dEYP%gAENWVEAEX))UDn~5LqkERqTyvh`~pj z^GA>=jVc>Etz_Y8eK)HA`VF0tiE8Pf(@~VREYu!9F=B4>>(E`aZDIgAZ zlN$@owDR--Oh}2K6oqa=d44!!SZR6kj8KLTL1Vzl6$uJd>*BxAoT}U^^#HkY+Ci(^ zVu?T=BW>q6p(hI{17ylj;2JB$q^;>XAxQ8z3Zx-x{)FN}1+jCZYj7_!KoUey0l1Kq ze;+9jU7`eCx^3CEwad1RUAAr8wr$(C zZQHhY*{(X(eeV76_U&=U$Pbx6AR<@9v(}u#+qX~wkvTI6aVi2MeF!n)F!@kI8018T zOAUgIq<*EHXX(o3CmnqR6q*3GhSc0VLf_$SOKe^I9^A4BmS9p`bZ|_Dr77DZ?gDD zpu4R=%F$&CjM;W!QGvDDI{O8%dYw2e62@st;yTiXE#Wa%aV!e%Gh4IKEc6vn@lYn* z{UVnAZMYho3{s@x>LugPOk%3VENXI!uTAw|K!N&!z0D2ho}t~>w+p9@-Ikya$kV~l zjPc6CC+pHs@sQMgM(D$Y{NMzQ14ZwiM)v$B6e&pI&ttoR6>#z6Q&l4(-FhpKd6)F% z(gF8mFUE9!4e7;~KX`K1VN3LbVVf{6+InomlcjeEUKRJ!jLA=)loxElKB6K#7Re-m zGN8CC%uu_GtoP~b^6B1HFT(rUZg>=xgm30Hz^_-JHXdnHVwdGm3biUgEK6l|n97Sa z1kTUG3UvRR4aK{&-Q!j3*D3)g8vy%cWNBo1w2A_ymP~`jn8lN^J`Ni}U*~7=+#+Ow zGy#&plHiU21^F?=jvQ{_UmZEsDY|kWq)hE1z7Yt*FN_>G4j&XA9~7M=6rCm%UiF~x z54?Z#(8v>zs4@~xm1<_aWF+gWCGXbLh;kDPejZS$9~7L>iq>=n z-h#QoOBR8e*hyMh3EvDkB^9hvzx+&Fw)uIYVyle2QC93eB@;UgI8N8&mu(PV?4it{ zUh2Wiz{J2dhTT;%J=tfST!1LDOuMJV`pHW7p0f%mfVHV}weV`GD9}sotPC^+9+x>w zbEk7swX3(-O|{RbN~MoC5H(*`;2EX+7j12snt^L$c|BQT(pO{4G~0gCtFl=_b<(}q zZ)d6kG_Sqy64~%Cus<%mEv5%%3U)?YYcSrodXP$cJY?@ep6+xy9G6(uSTAH&vLk4Und?p8TdK*ya=2s4u&&# zwcT~!kmFNIn-1GXxt{pwlw){!_a_5RO}w4{e(-1czV5$eeoPcc4&dI8OlPHh1* z`W)53m4@G%`IEIyHFhLNbU}sNWccRPXidFo4;)qo1!o#xehhNRHW5LyOg)MFoY&y6 zrrlMTq{Vu2t!kqY5^l~wW=wCpLZHWaW?e4muN%{TF9R*fTaE7=+pfsJjhZJau5V%+ zceDmc=NhLLNySp1oJmINB@t!1f5w~@Zz?`jUa#$z?`>VK)n-r@G{N3eokx*5tphr| z@`^3pTbDPsF)z-{&Z(|r=(KyZ>devi&?1q2j7?JJw-;}mT%Q;KEs(wH-MYATme}Uj z*O7ii25evWeKV15(T~;)N+ZREOSQ-BIyAVzHVmwR@XjnEY3w@;tjj+cAs_h@)R{t8 zmRYAup5k5h2N)ZhwyMaX*^)yfCMSeWljgKK>%(W#7#p?wB(r_0tK78g&)+7~8?j%F z->Vkxv6#~QGVRr=cfiA2q0RFT?CdcU$G>Dut<*W4m=3Gawh}fImJh5ka{=a8c@S)) zo1yy?IK1`L8jRGf?5THj7dE!hsLmsusVTxo(OQQj-w&$AYs}57@Ff&+B3=77b-LSP zr<3Hs*YbS8gC6+erzakw#z&gj0}9<(b0SaoUABTf?@--Pd*EvOdj~J>NV`CHBeZ`d zF@rA$+HQ0{IQT=Mx00{QUKqVGyM49?@OOw_D83P~hp~6!LW~R1FoU)*3?W#9QS&1h zg<}v{L*xt+(e@+6g&S!$OW2W7lF?{|(`T$6(LRSzhZ2WuBhn+b(VI~;Be)~9hlGZ; z^`mRnmrQu9cua5@;L)kkzSuX|qfviGOh+IOi|i-Zg_z7(aV0_*^_$|bluGqA#Hr4R zHH54+B>y;ZRu?`s`Og$SoRc^aY71+gA$26V%+X?%_7+v1FFV0@=j@2BF2Xt?Zwt0A zSU<{mpl^%cl)NnRJnDDk@`}PQsGe0mvb@v&w#qITKK}6t$SEp4$Mjf<&vqhPyyHOU zT#xw&@vzC6T#1*1=vBdE-gJW8=csZ0+EYrDo_{ar317%w5SlqbL zKG8nXzSG{{KCXVc6?J+j67W;%0R{WP_n$4N;M1+}exSdi8E^oA-#bA72V(<$2RdT| za~rz zr!-EA1H;Ho0Hjx5Lrhlu3kTas@Ew8Xy&#GpLt)-TqAeG2AGs<+KQN0^O7xI2WD$&m z_iwm)1b@q7tVYF`mfs3Dw#nzdQ;MOt6V=#69U<)W15Pes7z%dYs~_FENU}pa0#IDa zKN4Y5O0zPP81yG*{3m;R`8goLdcx%4f|N*A`}ig!pxj?6j5!awczhEEx|msrj*&zlTGEzAsZ|q=EF^v1Ng2@D#GU!&sDA8H5hEOuog$}zQMtGglsgh3^pt{DC}IkTL7!M@sUNdZx|s60#-15HkwR$< zadEWA7;wM+dZ}h8OFV?wMvxenvzyk5BEmvZ3f%eajC!}22%R81!q^di9T0dxDpGgJ zddZGG!4;O!HMSiY$FOik<&hHEV@@Fp)#2@{0(xY(rw()ZrJp3JAj#qcT;CDj2~DOFhq0L zh0e+G(AvZ^O5?FJ&XyE>;%vktnum zi_JPJCnNKbnr7jTbsL{0Rc|NRmG|hv9}YfO+?^y|ey#2z4i%&Kli-+ghKIEX#Z1R% z$Wa|^?&L`|m6IM%g-X7m#T|doI^6%!fW_n}y;hRjBK%-q+RIk#43F>D6F47j0jk zeXf=Z%@@`he*5hcN3~j-7C#-A*O-$_S<4-dD)^li-X1d?#)G%AJ4=Xa+DsSMmmJNi z%o$B(ul>I2_zQJcUksOBF7}t}zL4h~5>r~$Bd4oPdEd7EM=IZyn%Db{5T@4La|>S{ zF4wo?oLRb|Rw=xHZZkbrKLMGJJzUpbuZxg_ff=P6JU7;v=|5LGos~Cz#~wH9{w}2V z3-yk^YCXR1(~T@yzK>c;Kb)zL^R9IYDDHDIy12=*bX8FNV-Eh(E^06v^;e+MV*ls<4eWs8p#lZ~Aoc6F$NXRSZ(Gy)c;s$4dJGtPWl2yV})OTA(?A!dDJpbz~Z!H-~GB~JM}r85p%WK z>P{63)6(4}-=THsA{87U6eJh&sj~Ua zez5{uo9vNb^Gae3Y~T6C4gF7Nh+!r$pv?xY4VI^a=jH_`sjbclbgNgT%}sm_HfLDK zn;W0%znc{7?)F|R%+EMPHpHw3HRCtte#b8X?K1lo>81TnjNoP408{Y)p|-V zjQX<_F6d&)ry(gO?xd0fzr zvbphKTAluFVY(LPZbI%U^?;cQH?g;DBKi|}{`4#OJ~S>IKb5@QAwfF5_*e7@JNgKe zXXV~kDx9Rkj)ZTd-snHdZfHrq0m10~D#Wx@9k&U^Xz3XSYQ_#Q@QwIEwt;B51_KxK zjFI6mx~3NXs~*AY2N;smAl+pp+P`DyF!|N`MK$^)$t4U=G>OYSv?O5Q-tsuYcZCJ) zVNjG#Q!KN>(K##Szj8R1{-b)|i9;nsAESZ^D0UUMg1S9WGn2J6ENo~UVU}!cR7HC1 zt~jR=5OIB5`>rY|1?n>aLj`X3J#pBaeit#reo3`1Qa!nBh#pV_q%e?3djldj z*r6mMF|zdE=EwUatWP&lI_QOR{s2+ZT>oNKJ&gqUO9YC4ylArfNte z=7ghYVq~7&ob^)EN+qtM#Q-Oh9Ma`MWw_ayMRRB0WKvM^MZlUeC(eGa4DO>P=1YLq zB#=Mcr9k4r2jb+sg^MVvrFy9fk6GM8v(O9e`oS}h3vY&4UGj$h%wTk~A)VNRQm~_r zpT7|0v*z!WeX%~XHZ1f`Ns-U*| z$f}~-EEAIGQ+JgGcO8f#WVu6}rLi+7|5dd;mImHscypWF6HtoDqX&#AbPzY6dn*V> zsT^qi@3a6Q3c#4uey&71J>GzF*AQgj!AO5*z({QnwYhU5T`Pw9#M83`uN<8O({tlD zpl%{D$*Q5YcF8KGUsDT}^_^F6vIe&u)W_kIgh}*9e)7u$n=x@6~OMzEBtG$Z{zyG+bIGg)+YmufF1;t{Ut<_$=A8b!=cp3mJrdm-cqc=XxOv z%p``B1lhQ==xheX5u6Cct`aN|>V&jmcu??XK{M1*=UT_YiCAwrUTXY`jj-CRHQx1YHQGDeL!?yM#QmPL5zvkE3Hf%N z4!y}kAmd0Ni!@5Fic=mCi?51zZV<3Zh#j+b2<0Y#AD0amkWwJy8Y1f@=q1X{U;C+k z*8R_)k;{iuv;Z&wfEfq?z;6@o|MxIqZS16PXl?X=r`N0%warjeQFn3 z()G`x(AK|5bus>VRS_=)sP~iZMDa|1Ix0|!cI09|}sx-4q97*K#V ziMm4c!jK3{w0ouL1?~DkdC}psx)@Fy>LvEeO`^YGe{GnG+!tAKdcrqwSDX$)0%?{L ze-tQ%g<-(<`*)2^ALa0cC2Xq)pzQ z;JtcMs!>ugI{pE$x~I|e2^OaXFc#Ox3yB))^3$@&P9g-Cad*pL)otQj5)8lq6zxN< z1K9=zHeNNY>3|u4AHMx87@y`P) z>&ww7@5pR%KHKbu2fJm@J#Fm^eKX0tfphOfiwnjIGAZOax%c%ulg*d!t=z%>Z0CA? zy}rPDjt}qTfw_0`-0g_4Bk63V-zBI%(6Yu>ol++c(th;C3Aq&@7OO-WbHvJ@c5!8+ zC&r23wIv2-@$b7y?|3}-z+;q3Wbv%!;&9?2P23p8dKY5?c8xK3WBcdcUxkHFfa|z;+(uOzr<1wqX7aSI`H_Wk2UTNp4fn7)C3qG{el8yIF2tk?T742>Z8 z!l^Y4HP=#x#7K#Wp<%^SkE}YGQO=r@90V6wVL^}tGZTw67m`A(d?qOJ*Xuae?Z#R< zug+7P5}BbnGP`X}tR}^0)bV%SU%EfKJ#RYs3dx*nE^3X_K4ZObtt~ed?!-gJ*Cyzt zR=t!lp(^vo%Z(_xxl7hU4im%Af&x&SiIQ;OMjH|+Sg^3C!(t6Pk{~L@jdQ+XC_0fW z6u>FD29ehpj%()Rn9%^879@<*>o|+mem%q_Obo>_lx{?LF+qR%y;qF58CmkxC}Nd| zwWj4zGb@Nm2L=HEd=;Q_B1Dqn&7{JO%Ax8iSdegK>h&hjp!{Rx$eGe3e#vpd%;^#v ze@O?*laMk~<&xvv8j}& z2#OoCqehQ53?kIYQQ{S-G?WIH-LjEn zXSjHFV;%v*GQf&7Qj{$pU2+^9QLHP$O*OZt6B|3TtU5;<@BnrP_hW6|TMrrUJnHUUPnnL@l2ezudMejofHNNGb%X&Ro+bflP8wl$FXNbHyN2eoeSP zYDZS|(;Ce|$){M+(&-0*UBPA!=$7Y;5ZvI+0&c&$tG!yY^-P)w;X0(1a@@MRAa?bu zw&d-f~)D;Vxsvzx((E*IdORJ}hiHyU<04EQBG zxPPdQ>bl~vl4!_V<0paJq=84T*M^wzYW$vnrcL~)@+eBu1kkqT<`i&S zAoL;^^dp0O;9J+uL5XYR z{F=j0&k=z<`;qNE8~{i~#JJ(F(ftDB7@Hut^9~J=*x?qA!+JsdDVO3vLa71WC%-g1yL>)kjeg`p6&~yhiMng z4qM%}zv?5rZhnq?6Nm*6P`oEh3Fs#90S0(mf6Vm21T+$`Q@zhHrh1#cUD(KYrL%)H z2oO=Ez-Wda5rapLL$bAR$<%bQ$nw35FNa5YdROU4j9e}P4a=tu3BKb3=YzQCC z$))=j5TR3~@C$1V!<9uaYKynix?mr;2;tbb;a(8{0qAdv%h_Vr%L-8u+>>LcV^PvSI)`~x1uWlxxyN;*qH@-g4;bxEn1MX81gie@ zC5U@PMIri!&@DT!0KsEPM}i0l1RAZ{uo{qpiAj5XOs9_EChv}2)Ga2Y9CyYz_T~Uj zCayzpkcg2gd+>#tb=1Jsc+A__whsVwClpli1k5kOp-%1&yS(O>1pFlfbZX9EA(m6q zCV8ItqOZWk(+-%(>3AS@2ppEn30@6MMx|9pyOCK9Pkn7o@}K z1_S^OXealGYc%r?cTd;ZevfQICsN{hZpGlfE}bBEFzo@~G{vegne`WoSb$w7a$c;m zXHKmD{I5pwOSsNw9VsZT4Q#XEc~#LD3JT6#U1h#N1q3$nRg)dga8q~Kjuc=M#1vA- zYX5oH%#wFpaptCpV0T(}w!jD&p<&N?gxU<097Vu9Mlk~G1_q!Kd0+br8Nm6Egi(4t zV{J}@18no6i+X-OoY=O+?*rcoq|hpe5WRF4*8x?&_b{t(rykZF07`<2^{<)(%lM+SQQ-P3h`{@@ww`siHDO z=H#Ivv@(#jdT}!;m=(0s`L>>4tLmF$qxi)DfCiO3S7$-nQL@8QM%;Cp;+(e7>KLjf zp;`6puVufPb;tY$bK!Q$yfM)6VzkRF%LdP=*$Yl#Bh%d^<6yqVABxugQj{&Ye^KjL zh9?Vh@F2}lYA;?JbC&%S{TNwt%|klS_~*`b`RM;xR|l7cgqBO$l)C43$Cf1@Peg8L zFZ2xYsv5rbykj6J%0gQsW|+;&;H_8!sz=T%XFS^ewM7^H`(+awDuD1>rG*3CiV45f z)r$)W%P+PMAewXO26=5N7!?qE(1@hU7n*SzY9#zNgy-|*UAO0UX%->6+C;-XahX+ z8DAa(-RHU9l^X{An)abh;|tSldumI*7%kocgVwk?3BYdHrxF1Wa9)V)1k%@GbZoo^ zhW=_yGXQ3~Cz%RSmkRgC{6ZpyV7rGC_d`dsWar*HSrOprpC8#XlcX^#3@NY+fCI3# zIA9%s1R0;UPHNci1PQh-WdRCI{=tAr76gu31RKkPQTkyF`?>e(`i=cQL zcz@ivXXdMv?g0~Hbw`ie99jitDbmlFa{kxICT-dnp6?}@0Y9W=3w)pM<}vb2cZ;%^ z9+L0bx!|P0TWE+rjo659h9}pTWXt0I-ilc^sI?1n#P+5`5PPm#Ic}O}nA4tPd5>u_ zb3fG$y>Rb06<=feD6H6I!W(?Gqb*wczB)vQ{M|i>&tYToIS~-q$Xe~SzjScl0FUQ+ zR?+>kU9zxH*}3EMo^QPS{x%Zfx&f$%$%`mm z4p#4Jw<~svck47ueRuwKx$5rg-O;&Z@0FYN`EX9GjE|4?OMYqv9>&?{WXtJaHn#C7gTPsNI_wSe|^x+I$7V539Jzblx_tJxNE?%C`tKAqC?G)Z; zbgP%%<%G-+zJ+oj9?{zw^jAJDT3#2|*O}3l>Yu@S_p@4_+7x3QFY^yyozCy9Ps>k< z#pa&fE>(3|-p+fE@0de6u!n?gd|4G=7l)(v+}Td^X${X7Gy4AOl$)>NbIttxS>3Nk zaLbj1%1b_<3+MWGQMO&5$4*&%7aq+s3J>Eed7FRxtqJ~HRH2r+cG{1QyGPKyOmEla zyS;a>g=aGbB^B`Bgg^II(#=>pvItN zi$@Oru_q!&$wqirBuEV#Drcgwl$33LZPz2NQC+-Oq1Z%{oyEF|clZ&(l>TI4O2|md zge-SDd*78S5ktLKO~^6-Ri&P{A3=+Tm6Z}nf?)bEwBY0$0fJMx?D4s(| z%#*39PUUfy&ew3Y*6#Mi3Sxa{3+nLXT8(CMW6nUjsKBnUG!424@GhaR>}}a0>wGla zII9iWdu2~Nud%79DYRTsa#FyY#0o%v?+vzZqvz(!!nIj~kB^cqADm!U)Mbhbie~v^ zI1yJ+VsSP*#v*QPQ1tg_xP!DDZguMGszXDbtfdu}MDY=H3D`97wSMYy7n%Q%nUJFm zBlQ5)jijb8xeaVpAKm59W6Lkoj>)FK^1tTFdAIzz?AdezR}XZ$@LmoHcEW5&H*ZzC zKy61{4-oJM2H68pxdTM+Fz|*F*<)PyI`3$`(09Ur<+RFKeGFds-&~(8UVJ;D_Ox2<;qUKqac_`|!Se0_XFd;@$VvU_BA;$Bd>BeQ#ruQ)z< zyzfG ztLc0*0vDp9uvQZ*vyzxPv@~htC^cJ2)n=_rOrO6^80cv!C!EWhD6LHPXQ-eiEiP%1 zX0JX#M9t&YO9`})9T`={&EvW^=M77PpstvJ^lVQ|jw}ahwJ;^elv1K91G0%Fs{EZa zl2&Y1cjqY~Hqaol=qWh(#&k{sEGO?leRLw#MZ=b7$zE;_&`OCizHi{+%b7Vo3i^{j zvouDsFBEQU9HS(YBoV+-Q8|ynPeG@k3^#QQ#VMI({g1tN%z=n6aX_Xj{ShKJTz~+i zDAAll-XvvaC}~?cBP)qTJ$y3UOa^bd(H#>F#obhd8j!{4sH*A=6_SIga8utAiN=eB zUT@K;lk}9azD)}+P%sHZ!op(3>Eu2bQ9E+jnKidZkd}&kE&!@>z9?9^2$JMR8drDv z`r_Z%5YH~;I}mO^oG2&$^3l8?X^D5WDF8Px?qynrO3%tDJnuK0CnNHrvwHop;<3AS zpi0WczqYEQ3(oII2?z-^6o@=kCD*C7fRyNeq2+mH4XS!4pcSvCe$;^FC7?oe9GN5< z8Nr}aLBFyXqp2|VF}-=iSM_s^skS=NA@3;vX*M=@Y?Hc8Ll{J%Af#x*PGS8J+~T@Y ze9<7=RI-3{*($v?J^jZ}q~mn4|r( zBy*vktqhatoBv4P@nCuXmASjTD!)U-z%USbqs;XmvbXe~iXRfcuD+i;Cj0Q2aIeXO z8`rBjVV+(N#HFHRjB4SmUysCiAZ~V$exbN9(}R(%-MIu-o|NH;I0CtZr-7>I^^d>5 zt^4Q%ZM)aQah*IY$C&JhJ1*;TCcnL5@lA8o4^Fdx5lx39w8Z3dr1pmci~>ipG}7-u z>a!I&sl%Q#VGk^;;f6yH5hhnQOCtAq)sum#n$ixcNU=cM&Y>L;NkN7N0gmI^H;JUx zZJyx8br8h_BdWGdPV<{JS7Is5vSzADLBA8y=}xkD$-rP(f>H-zVk5&bXp>^bXL%xN zT1_#mr)e4$&g}imj}Va?w$f|PAnA(Wr%GDYLyt*QBP>IF1pUNG0ZfSCo&uaJ3|N;# z)Y9uACF$SGPz$f6OEI#0U_US8cXWi636KUtnqJn$fVAn!=9J;qC*V(&fl5GdS?`E2 zWTb#-gGS597l|JBN(8DqY>_en;4w{Z#NgriVTR0IPQ6|7PiVRN;&Vq>SH zvX_q-*@sPz5Kd}O+t>nEx9s*t8UkiBmBXCw>=K||2UlDvmSJSa8&*leJpd&6w+68+ z!&FXg!=g-KKxQP56+#PldYVqdf7v8pR4cA+o%s}uyKVuRDhJO8P>}+%8%EJ+1G;nO z?!nqaq_^9?QSNhQOQa8m%WPP=lvPET3Hqn|NK5#R_~unRi|e-+Hq=pG#iuuhQ= zr1|AmCnU9QX)+Bw9>!9Q_%siBwjx{tpZ?8m23|Lz2;p(6a{)2V54oUuQ_MSDZQ+(Gx?`+9-q#A3jQIq!&WO(|vY~ z$Bw9DHoJoYGrT#10ha1LJqz!vN&f!kStWnx7(o&cY|yI+h#7(lF|kv>6Y!oh0J{=} z*ooV8ppb$*m}pX;|$$I$gJ(9PG_~iuBM+H*WTEpxa6Z;1>SGlD$ zTJ$#At!b_$bj(C>aYW+Vp*`3E{|842e(p-#hg1ZY_9|JD? z=X*^XUXJ%ubRDmx))Dqy()*0`e?_aIl(pKcRcH=|WX6JEx=B$?e?XdEN3vK&RyYbX^b&qzi zcW)Tp0|Xnlw)6K0Zms;?pzPMmmJsGi@)ykm=aureY;DcQF_)?A$Bx&(poGWuUiP17 zctuaRMrk_3*?48k8P+V!@57U))bi-r&!@hYrIl>(-9$Xk+ppZKu9s~ZwwxtjvMGGe z+r!Jgr^zC4pC;<$ajTB2iF>8bse0Gu;#6=t_p19I9=h*;-=Kw9#Y@JW7N4OdF%V6=e@XQIcM z^~6n&G;I(0YoY9gu*lTki)j#|aq`HlFG_GL{$?pqs3>hf#i$(e6{Q%rz>$SF2hD+& z1(~Zg@Ue=@zl^2LUgkAq*dU<(>$xc8)?!~pr>hYE=tC4N=?jHAM|;z~$>HeC(5m74 zeSX*6UdySWZlRTX0Iw`cXy<1qu<+>RMRg8kUZB(aD~t%1A(LTBL&+(kh}K4Xi{hID zZjko`3U}cZC;ax5w|fWDb0%B$o-VYPubWO&vMs7n57B#0j+a2WKiqH%=-(@|S-xZ% zQ7L)F|3zcf71s9heW3f-*S|+Zh;|bFaqEnl*@Zf3k+ykB}gw%Nunv|G5R=m%2Nx-KSYg>Vfp zhWhCGEhQvY5-Q}SCWZ@`s^L%_-Hi>#p;C_O;wLX^vTVA~G&;DcPMwGK%?6=zRga^L zX9qGIL>85-1dcpumXM#3|zfOZ0@5 zrxa*J7ie) zu=u-wBt@#86zwnhv_)XaiAQUcWL1-A^a@Q1jh||8y6g-Af&wING11ERRTwHE+K<2gPD=Vnzi0# z)dxqFtW;yy-^*P*Ce$GWKC=x)TudP@tqwkkB0b(lTP{OReM!ZX-$W};ks-!`_rl9U zkH>)lb+q`6E!1yEfRe^PILFgxq`h|`4z5YPO5YX&{NvgYv;;eBig9Ye4i2RFo=#x@ zJ_A)Ecalz6uYej45rKq=c*I6h+7~2~AAF|7qP~+6(MU)*^e91&DE*3FZ2)-}NgT1| zu1X}}cwgy484HwWgbjr3Wc-emB9$)0eoL#2w z6e5^k822JS_VK&~e2K<&0}R<48g|KgfFK%#z!5q{BNL7QanAoIz{m!;$PWR@gM`5! z2~KSHPxxgSg?7l=7il|Aedsh1w`>Ly_iS3BFu!6+r@IA!|amaODRBtj;7rFaB- z$^%{sGQjQ?Jv>*i&%4@Yf9E_6I5A-!lz**$yG25rm2-qUn92$Swdx-+ zK^zi6IfHTSf_zF_sqCrzerg8+eMyQN zK*9ps>~yz`nFM*N#5!gawd2wb5}TZ_9^{5R34V-W|MKKLi^T>=NW6w%Yj|5z+la@k z8xo^3v{-_yQCFb433UgKC0`})wtN!Qpm`Ou7JN3KcPee?(!Vl%Vo~(km>S) z>CGJ$vj)U3+($fOSngoSja}3JAQt0}EDIn~SU$y3FvF7pLf~TSLE@UGY0)ToPw*wK&qljasRT7$HGl6I;sr-ZBn}b-6#4PM@`kTust5{{cWlBqfuS@x`HuM!FHK~UazR0b5%TAcy!>zgkJ^*%GWMGW z2*s_CX->Xm!XM@Y_J;oUK$60%l}1}4K_I^fnsUemSp}b9Jw=Pb*iVPrF=d0m0kK6I zwu!?`PBXQyBjm#pfn>az%%kpMZtNQu2Y+}MD?3V5VqGauClijthGw=Dj!zfkLI58z zq+f%)OM;w|UTkYlIO82@;2sB>A>tdf=Z%BrC3ffolu`iYBc7*LqCC~%Hn*d&oCTFp zqX(#fS+x$rw#Y%!MV;jc)t%Oj2LmE?@P10ik$L|i>;$4ASqke;MN5nn1mzTnR$_z^ z&jQR<=__MsfAedD0F&7(8Q^}j$8MtqOwgdpKlT$~m!}0fh5ThZTrpJ#=ECDHs{BhM z?U8mu)LZ%2{&pLY0*!<$8?|1-swU#uwQU5z21dvk2A)2p45T{g04<>s))JSpoDs+V z8s#J?LB9yh6uI#>4B>DtSWuYs?o}qGU7jBXVcxvJGgq4eoE$(KbD!PRp2A-aP>e1o z#-LOkJv*1DZ}5CR19n_ zEQcIlh)6@#>hiDLMfw6?E*!$jO7<^(6l2Kvf?F(^NA`!e)0)d0{i<0f zPP~N|)hOeN3Ae~5%eT9l&2OsC@MH9C79`#HqEX;vEltU`>8YJSx&;pea(#_C^p^eS ztPMw__v8knRrK8w{JhS)tVd5P2iltJN!RFNsmCpA$M}@r(0TJ2`aRfV;m3610NeZv z6G#CLsnHvKgVXR--nzDshzOopK(|#5GhTHS#-P47__w({KFf*V&o_{btmhZC0 zyV3S+qcVExI{AC|Q}3TI-kr*pZ<)FHQ~jEC{gFb^>6~+Wc&6# z=B4$=aC!G3_Un6FD3)(%H>KZorsK2*Qqt8|-m#{kv;HT0WUpn;&D`#XF3*^ zw_di>*ytfubl33ub)3p|0-x`_GS#)lqKpWi*5Y=y-Pd)p^xQ!AVfs$fW|zC=Ij8XD z%A26h@OJBL5?t5gWO)mm4A1v0X41#yhRieO^8LxbvAJg5mtCpzu}fZywdqvy;c1*L zm+$fU^xD_E=f-S#h%Z+b_wAzPU1>EYM-~2SEcD^L(J(ce_j!9|DYt@^Euj&01ADZo zdzD2MPdsO9vFB?OHh0Iv>Pgn~n#;M_<8!OW*X5i3zV%{9GRwHu`(p3~ceeiHfXwWW zT6r;P7cmZ!05Vf|1H8LMrv0Ygc|%sxD*M^2bQ>5kjy3bb?@Pzz#b>hZfniqX0=T^S z>XCYR?Ky*XaPEwwgGQDH*cdZpr>ZJ7ps%a9M{6Y?l=paq?JhaRf%QjVlx9Sruw$W`z z7GX2g7pvL!OMu-ztj}@H4vg#Sla#6i z8@autzAb$eW2(>U<}UI|AhtaKxINW%zjYfj-H48;PFIu^gp|{TJ-PVDt_m$#(w9o@c(~mZ0G-{%2u|tLQzKP zX>{F4UvF`8G5y$+$IyrZYT@eCG?SD}v+1NEDW+)>@xf^QNV6{OgjkzyMmDxwLJ*JkFC9-NW0e_bLP@zsepQH~ zLy|-hQ3xRg@iV)tC8I_kl1M>?2}<#@8(MX2DrHiWk}xJMZc5ZG(1x;Q>GjhpX@f+y zoMwxk_^=8OnVWZ5vAq&WLW-GIt+82!gOc&<_|akfcB?~}Gc?`*P= z6}W-iAc2~6>?(xHMo~Bst*7=c6+ zbDu1-l9ic$bGBJTrUxK+w5UJ+lSo^}?g;mL1*8b4Ep6(KF3`kgDHl(BM=}w;Vdn;AhM=YY4+~295QS9%bMKHa@DQqMAS?yPpqeE`S+~xHmT6p zmer6q43FtHE~x9jvaAnBgXIiH2cPI$cyvpHW2zYI2tp~jdKtOE2z)z{{-wZHwFeXT z^N=m_U?;|?wEVjbqgU#@hwAoNp2WAtt9cKW6i+P8$bEBO*I7oH%gXWo}npOE*g`{b{_~FCE`!Xm`x5 z_M<4*W+#0D@ACF&gc)VSF-}zti0iPRXN5hveX0ByedfRkzJ??h4i)z!; zWp1oGo}ZUtOP_Y3n+guwme8wj$vVFepgvk{WVD;EEtsL9&vYeqjzb9G_GvZhz#*Ws zx4*d|dIS@!1s2a!=vCQfsXO^l_5)ySgTz`uqc80={QbX{W)0aY;JRG{M`s;7>4LK~2A3FJqVw(< zE;GPN6V`{qrQ3CH#8mwUmvR zaB48|Y5(FsJT(pwu(La{J}xjc0XJBBj!CFSdcb-Pc;n#DT1E8+^4B_^Rx`4aRx{r# zSLhn`ctt1=eVF3Tx4nO`~sjic#W3zR$qLuMu z%DrX%(URa#VR-}FK?0O)^UeXyW6FcM12yvrbAznME_a#gM9OF;CuiXBgE`67eKMsH zuxAl2X7y6Gwy&I1&(YDue#c_^--VSu+%jdD#Tx4B%*YgvJ?vSQfdzE?B@7D! z0&7eZ66t;nn$#T6v0qrE8-R6|+MT~BlSciUl*5iyC(2UoT}dvm%-N3J>J*I%Z^|<< zT>BWx)ruDI7u>tY*4>N>lU&ay^OEKAmKh_GpJGlW9Z1$oq}V8_!Im?;WvXs%PJQEf zFgi<6eZocR6>Q6|%v{ZyC8cUsC}UNFO;_SIH^xxIn&fPXWWzEnWJg*X*;oN-U03WO zA5HwMiqw;5;N$MWY-(c*743V`($UjpYsOe9)NPKJa>GJit)5{ND>=~}8lP_peA>K8r`iJe^vaZgB*qAiOn1}5Z zWyOq+SxI(F-ONS&9+i^K3TBIyA&2cjL}Q`f!=k>k(vZ#X5W!vYlqOUx@z|_BZ;$&* z=lCUNwuMW7!J&q|iLOMzPM5fEmPWGSTM(J`1R3iaJ{_CoOH}b)v7OrUxxg#h9RnV6 z%!juiV7qquSQfk?>)6L7ODa}KC#Kt&#AhQot>IFr5FxK!U=gc`H@;|s#|W8TjwO+1 zyz%}_j^5*l2C5#Lq=Zpxup3@FBz%P9d8Q9#YZl2;U{9$*#&!uX7M!!<3(tS_dk$jE zE)3_Yl}{1^7Caq~hoeNgaN=Nio=bRbQ|t?uI`Kwbx52}R(JZ}`L)E|dzQ=ifm zUl8tB=obW|mtkx76l*O-bzbaHYYB-L~FI=CVMur&>eD{BPe4$@0Z z_end6S0(+qIhiSFC7Ve_(@QzM**z??$t~A*f|x{fg4)48I2hs}@ex{Zb8#?KManQ* z_xQ73Gy^8`7>TMPRcpDwBsFH@VPmui>HQKDf$yo+EkY`dqtI`{o;E5eEH6%K$=D5q zv6aWK|DHD=*6ja!3I-$zzxy3|VkuKy2|b){hani#DLS{OQ$Ag>R@|c5Vfd$6=IM;E zrbBfM0)mBHlZ2SKI4U0#3Q+>drbAvPJ{ZFdJP=i{3a}jPb0bsQ0NmL@+9gaVl>rr? zObZ4hHGJ`fVdGquaj*e-AJ@k6dqy7Y#46NFQS;#MHqr$BQ8WhOU!hftE9DB~+)}Ef zn^T!;KFbM(`Qlk7cWI7u-^C@*DS279t{PG1OBbKYAJ5LWo7T!7nRo5AOisB^y<;o` zEJueCp2a212#X0g`ewOi8l5#k7r!+Nh!6`}A!A==WK^sAX!UrYf>9k*D6luW{8&{m zzhFYdfJ^%Z85a$!F--V`5JqH>OAsWdtkEi9swdVo8VE~mN0xKnskH%&RCIP!MR}FN zk%L8e)a$ulXhDaeISBeUU7#ia07C+uD1RKg6?dNeI@L6q(4_0kfu~e|QCCsa05gd( zOxJZq^?SboTmVChvA>D`ib754g2-+7FWHjj6R0ZFT@a(Cv`qsYmi-4(T^~?9Cy)54(XFH|gFp*lBLq~84+t|5O>5<`Xrn$~ z){;ui-S2f{qOHlW`{|E?hRmyn)he`9dKz?urF*CmPbX1Yq?v$xU?$d!k{bzk*bQOY ztYH+@nlcE}ktuYZOzo+sfxRi9HE;4(L&A^gEzVT_(7#0$?mu>373S}S84EMH8aL-$ zOs*@f%=KTWyyd2n`v>+(uU>@v!y$!W^;f> zZjF*IO`jneS587flr+}-OmK}Ar6^X?fCI-ozIz(PLABS2w4HYRPi zKIJdJhWRGO&<3Bn@G3&viC$k9?_)*5<-p>iLV8BRp5;=^LSC!Z*v}SJK4_A&w+o?g zIm0ye!Fm?*MO$}!afG$hRFOr|)1T}Z&!Q!W8Rg;tb>Cz)G0$(S1<)+=*ajy~7D23B9K>tVDR&ymHvAEtP1MFhxqR?lkZ$94@@ zQ4RKD=U=k9-wHZ7_8UXniTtAty~^4Q5|5F#y=+ad!-BX!nxsuB026yWld%Hs3+e%ZNgR13^!?8tF-qa z@=>t1Vlv!=8JXsKC$%ijcLM~Ac%1|j4Bb){1!bHl52NlcyzuFqrQlv8;GQ}OG=d7S z1-gT>{lyrf14#_xekLGDb;VdfDq;-IK*wBWcOxGjxdQ*SCUMG-Sqpks<9xw+uB=_w zVNtO&(&v$QT5_~1Dsg=;vkBJk~;v<;27 znuDdiJ=mPKA>G~KrG7&}?OoX8LUt9ItP?Tw$4t3kh>?!7fcevmc224FNYm3v+nIu0 zU|hsJ?irh<+*ZC^I(BO?Yo`RQ(2sf|U$tt&fgfi2CAThg$7f!7^h*!jrHEDMImM6o zQLu@Ag;tu=#PpKC%{+UMMrA!p4Mr&XL9$(@d)$EV)(R}Jv0iB5=)6_}wbeSNx|Si9 zi{8LYRyrvtbnXKor!OkR>$T-ln6$s zAq18|TgenNj4+Zoi5Z^}G<7elE0R5Bj7C>5nrE}m~^r1hOAtDy7^$GkaJ*$?k&L_#VWAUV>7{gO-D z^>=$ZkR-95Scb|S&Y*MPCYTR-qf^@zVjok?rn@squ7YMjvXUN^XJM&qmo?1cJ$E;3(Qa{;wGX`Ou~*ID)nD`!FF4fe*a&n!AFXejJ#`$pcam@K6F;k}ZPx^D zAd>NKm?k|=ra(e)Us%2ya7-j?)FDlfGlw80_mrjZs{t5%nD3fNoc`~%Ixl}MMwSjg zwN>8(c~0hV++3X}NYWbakNy$sPy7HbHM$13VRtZ?ZCO$OO9|G}FT&q?a@n#1j^2rdY)+ zwBo8oX<5zyE?Q#&SrcGllxiUiA{VAaUc^4B#PcUY2v5cVT%}{Er{K(&SV3Zy?}Ulm zfTiaSPL>?X6FFuF$>un33Vw{uQs}YtqFE!9N;jRjU~C~Zwb)Uv>$=jKFTiGA!e*So zC#k0)oHQRv+&+IItrup*k61K^UcfUMtruA5O|ZWi*Smv;Gtw73OwXu->F1l%zRs6N z2oHE+RX@&`J7YA(N1L8=99*ayz(eK9y(c@=nf%AxqLP1ZYE${sQkWjV2fa5(KHY-e z*RvPDAIvMj2k-ayZXsr0ZwNS`XtT3&)JS1&)`@>uU!%#ByeAi|DgCR)O>EK#Ow|O$UBQygXF#(%FEsvq2M2N4Wg8qO-FC zX9sx)dq=Q*RLSl<$@y90*}@s4AWh1MNLoqJWZ`5H6+|=lRyBQ^BSwbzR$h*-{kohz zw;Mr{Ueg;?av~i*$?XZ9$jv?-)fGvtUY_#W>T{ziag4}qW=ajqWFO`t)!~?Rwn>xaxU68)aZO#5%5V?-)PV)4BKxEDn)nu*x>V24VSdY93z)L4N`UWP@mo4oyXG2#j`L z`(n1gghG7w0JD%^2xKG1@Jik&md(D~Cv}5o2It=Et%Kd~x%XlK>Gmy4SMKHLgGi2< zpCVLYp0v<6ar^#SHY)cPY$Pi9$_lD}e zNfqz{Pq7NxJ!&XaM-y!V)kiEo=J7X*m+`^Gj>kx+GjLT0$2K8TvGs0 zgcEl0*m-z``b!{jUKi}X%ysuY!FP-b^&S=^^%+Ct5HyMVUN+=;BqxV+L-)8PsNzkI zZk6l%;{lt|9e73J>TeK#JCA+*U3#gs#Iq$*ZK3sR_L}t?8x}c25a*Clyvro{xgK)i zNI71_h1=Ns{5zO7R&WYj#mSQT=o?_9HYaD#+Nt>5hvQl&rzWwlQW3Xd(TXtf+fRFw zRGXRy{P2kR-Y(?}J26Y}?os{KCF^^Wnzt$k)eU%UrAgj7|KkeQHhz->XxkEI>aTS* z0Bv9SeGDDnjK$Pf=i?4Gwmv%rK=fh-;CvCrI=P8gKvYp}7JvG?*8rC=9A^~xUP7Pr zv=WideC%CX=jXgGCM=}%J$2Bl$n{pc3}MRIA=N7hc$eDS@^siLX2)5HQ;;NASb{9IiZ&G_1aMCd|!Jn_^H`5mw5TMI!^lDSnhVo zCvxF^{Oy0-9ne#%hHDS`=@a=IoBe6lWHaUs$@mMJY=-gz?rg6g3-~xH`$LA30>Y#R zzpj;EJ|2)Kw;0F$R8n8vxPv+R_kLFOwG81O$gTmFDO-vP@9~9E@|B4Af`c^7H=^> zhygW^Nh4S<^q#BD7^ww-D690&WNCbq5%UO%^e3GUBk6SDj?5bd)~|sxFC^lQiXCk= zm{W#+4$$a8PUKC6+($kpf{%$bi$Q~hMM~O-F)!$TnZq8EeM*sN`yCxRjBt*VBV_u= z#D_H3g(=Qk@^pi6pjM!tnia{kGy0imAZ!$oLUOFJoL7&zeHtNSTX?EB| z_ihYT^P~iVE{riOe~QZJ;klPlD_`>6PkEwXg32LfmHUCDdVzA_H-M7x@54y?mH+a$ zV!!_GPk;ccc0tGG1@5dz-Z(k#CN%jYsgQsL&JeR%t@jS7-EApZFi*e&uYO3 zm&0?7p4J`?((Ort-MNRSa2wJRA9UJHH^X{Vzm0wbM)Wl>unRe(Y9dmUl%n^PzIFN1 zJEpxfkx0z9)n4}-NH=#wSn4uc0L4oLmG@Bso_UBI zVHXhPkzk0g(Zi$qzSB713?a9C)c_>=4jnGxSiwjk{KP$&nf&<~YrFVLCbq5Hy8Jqs^)Tr#1%#h+5 zG=eTnnL4DOy}1$nJpzI*a7x^O%C~`FEdOx=g9-3o=*yGA4xR7jaRgxXMl0mq7+X^A z0OxM>I6E7n0Xu=`5W`F7te?>4bwfmKEmZI<5F5ArX~E#t0X*JoOW?+e5V5g%t~fxq zU+$5$8@!OtUos>-lS&3_8{(z?0GNZ~HpaK}xz8GAwV2wtaVC8x-`L^Zppb0r+s2Pt z7k{r9s)5T9RKTBJ^`poigYY{~i)Qi-=8VBr|4yW=;)DTJr2SV7Z%3@n6q~Zr9&ytZ z!VZ@^XSO{{6iaEEwQ5cGhNkpF^0mT4>(bQVac)vm$ot+Ct68Igkx9lgAJPH5J|LRr zQ-gHgoWH0x^`rEmT2=NKLH+UcDn|5w@5sj(Ox|oj3H}g>#0iKC?S)VBOZ)fX8xx5C zOJ(ih%Z^gw<7LW;e6fXFjER8?q69{~IUAR;n1!EP5#rH6_u%V_T_FbtrOz1F ze~o$xo?cOw-jc3_nT(mS3}GG#IobW2c*d_mcW8^y{Jc#%{%`Jn#PZhxhEAYS=TJje z1<`)5Lh0(fhfX4b!UVWb2w@-mpJezl9ekGwIV;l0kGmA5y_bAHhhBSb$Wo8ph9BjI zK2j))FRtIy5u9HpAxrWNX)G|VtELmM2D;EYhfdm2xY&v{P53d-3&Eodw@xj6XL)TP&R3N$=xAD`;dVY%Y3sh`N8} zK6&mrSR6es3ooeXT2IEVAO8{LRV3|qG?dtSE$^%#X*1opI-=+C#&^A2Mx_6>B~MtJ zdRWAby8?I9F=cS|enPvT%}{SJTihOZynGO&H73CHY_XR78R(QkG7A}XYTd5;$lowO ze583XotIwqTCwpOhzKWDiQB9m$p5-z2^$jh)F_p88 zb`n3`0&J(t`%2*!HF~OjetoB7_)YvcR5X&_*LmDnysz!;p-`r=%w;$)olJX$wsfBf~~bL(-{kzG5Lc z!&;u9_lU{(Z0AxYN#zHmoo1+Uh6A?L&8hW~%qLMF+jb2X`7EEk>nNn$B92{}9*)e{ z%>C0O)7$4QsfWB58MPBDHaU`Urs5X70l@uY?jCx^tE*jWkUJ#c~>XaA{|66 zY;~shuB2%B?Dbtvk5wMeZm8P_MDka5Y$^)L%{CRr;#)N{y~$Ib_~+^4b)XDnNEq7E zd1g(GOvRPtJttjTon-5{(s4_FGQE>o(#=P#*C#RSqw>sAMYip|C(43z^Gv;!UEl6J zq-wdVK`zXTDshaF-!b55(Y=H6?*Vf#eK<_*%%`dS@@GBe{r zWm(&V)Z^=v5vWU$Sk8)y@fHW$6UAkW=p6KVgP4aqa0^kzGy1G);dlvg7J%sJ*08(8 z{U1HEido;lZk9Ejm(RvPs^eR`oTw)!v$GHVhHvjwX4R=>-g3R7iS77?zK_ds+)ECR zFXDHqxUCn>*;>y6ap~12&5t!REM=8Wk7@xEkdV*qCsz-P(=bP05v^m3Qkx zos8ccTR*nK7i&1HhmH7|K4*oS%}++Epdw~U*siO(OK9^p3!2W|5oHxd4*6Ifp*^>Q z&GxhsHLy#s6;>3IFVli&CKd z9PI8D;D4!@tWi~Ulx_!k>$Jp}rWUipu)q)^+@phRiML?VEZ!>$=IO#`A}E7bO9g13CedHJ$ODr@QrI( zn@d^z5AZ~dj`?Nf^3NlR7@VFwVI8)1R962zrfXi4lAS-jPF&s$wb@Dp%{1>{%TOt9ycPqz6uF+>>y2uixuh}L{>0X*Zgm~<4YKXao>{m$ zC>#izJe+b?%WLKRIn&&?4H>Dw6%@qrLdGbq~=&`%;w6C0HWZ0EH8e*t`@8QnHGwq_&H1QbHm(esRG<$ip zEAg2g2h+E6$Z=8~&7&ZY*j!Vgl?pVy{x-zI+b9nK#W_l=~ckCyr`&vv@3xI*DvhB15PEDjI zQ^o0d8ys*EYY;R+A+#DR#@osEsF8Gzd{RUaMEpE7SZ5>lT)L&axy%*x0{b&BTtCa} z)cx8ldj{D|QgGoqd)uS*W}j#%uGaUQWDZoC7IuLgRzw zW+Psk+1zsIUEFd%-;^)IOG4$eI)ZJ(fr8PwSu8oNLCOE5d{<;}VYj0Ze4--I-$(IG z`a8qqP|}+CFymv+t52cPyXx2@l&+dArM`}wW>+=je>X|##s&**Z^&7?2c@=aff1gA za>2;5Ut;>4u%Hy{>nqbP=hEW}1Cp8T`?w!>C7(Onv%~ew5%RiQ%>6ZZl%d%&5vj3A zQ=ylw$b9sjbWhB)*~RRY;kyeHmZ)?-UG^(|%hBG@syPwN*71zgX{OwJqu^jXHwOA% znL8P~EuZPTML6_qc|gBdT{9I;#W{~e?vXv|9FHyzIj*GQEyeDe@KxVAP#Nn+|BK{N z(fqve&@qZ?rj6J>kxc{nyCd!DXx3{B#jxfi?Re4`>yNl8Ad0T!Ideec7xq+qU z*vsZ@yKzbecy0Dzt0#AHg`=`+m9XXNw#3Wx_GdIh1_k0cW~>-GEzYdz!BxJZ)AHjc z<8wNp63c}z$GhBR?QvYv>#;l3ZhAuKm7e5u>MR|n&Ssl;1|_VJY32rq@wREZn`ZI_ zJ*?`2k&aspt&v-IDSL0utKvLheY36Iww)Dpl+j7qmG8CZBHOajw{P#~FySLPtDlm_ zG@#XaD{}og$E_AEt=3zmbAIe>!Cc~LFq4W)MoX7Hj8=6uRmPK6X|?SH;Z^!PWMDfe zuao;Dw%Hl!onrgA2I}v85vUNL?IrRLWwRZ8hKh%<%O)(^Fe|4uOT8@aOkB&_6TK$W zoENd#^4!z#=g~BJY{JizR%DOf{jXCQQtxQQ?shCb?^9l<7Hz|;&=LL)xC8omSJ;^7 ziyJ)Q&@Ml=;1`N8>cK1lY+>g?YPg%+^$Nas!DF}Ii>^PPFJr*(_*K}c5N$}>K*(TQ1 z-Kd(IXJ|xB;)MPI!=u8{KEibvXv?)Xt$qd=sb5dUJ0VNELPCO7t+ z(UCB*(cuL!?f^l^5FrVIx9M$n_ImrC8v>M!w5<5*=o9*Xz5G9B_jL_{Dg6f^hU+SZvBF2C$;DEmlSz~sA>ep)OYTI44|dClL^Kb8CK@YY^v7w z>;>YHy(6T0A4t4Ye8@f~J}~1@5Rfp)p3s6BrCriS`}nt;1%UVh=v7zw82R(Dh#<5o zsgU2^Azh4ue|pp1l#A(CHu)I2DcPm*mk=NZ1@*(IzYWh?nFkS8AU@Z|-gfblbX&oh z6Uf?vaSg=L5lDkE3}n@jaEBlVq9E`EBghFe*~PSpCnBhZTnYpK5?6#{39~2&Z4ufc zH4o_&=C;Xkljg$DMyL&06{egKZiKrQCbxI{4VfK4-KV^XLL(6k!Sw-1>zz6xGkE0HU*bi$DfDPyu7=(|M4Iq+_ob3O& z$Jho`6W}NhV;kgo2ciw0vd3Z$jFS)E1>U^}j1G|34;Kk2N)eb?U`)YbNmwFGp~OTE zW64?~GF{|Mfomc@T{cDTWJxewMomFAk=amSO~GY}U?QiG416r}E?-IEC&^!30xPeP z96nJBtCYl#3LhX34+5gkum>no7~w8iMY;mN6AWV@wT2J{;br(|pP!mE8$xU#M13s% z<+tkb7x2G{Hcvu=`qY2W@jBRlskZ+$(dPIMZSmhoTZ|fvHPR|h?_=lCYc{sF_Y7LF z{g8zC0XwfBu>+#H9wH(eb8vL6jF!r1{cObeu&v*f^mjL5oenCh|*S5MG3?5fN~?TV#&R-DQh8DsWK0?(qTe& z>F&lxsvd7f)M#TYAu3y0aneZA9wP&gO$RV*H3QU)>)lQ z@c@Shq&Khr-OC@4SV(rt8?e_=6p+%xcH%bWKKK$Am`bh%_#R9vdp~8St63dDj`Zciq{%HeSNHiHXHq*Txf>9mj^Sg&bb&LJP>Of7Y>WhoFKBom!umo2 z%_|r}smo#hNh`>;!BO7R+FzkYgUo3zYG5ky1z za_aCa6+}d+4Hu(%!{3Oh2g7!1p}D^PwlRi4YD5PJjXC(RV&M4L_~__LRSo8v!Qvo$ zePd|dBjbWN$H1$56fix5`rg61uADVt5Y+L#Yt+taAn91gv4&|{gsfm_-G&LrIQa-q z0rP0Yp)=<{DGS8q0BMx=4(cc+Vt;|sDh$&o$5lnL{|X~>0yZP&;~V!tex0k^+@;hR z#Ed<#gb-qSr>GF~2+{y7qXI8WwjAHBjw8Uz2zW!rSDzd^sB21DQ^o591EgYj!|W{w zIlLo^|8Ye3rXlW=jn7+Cl^i-Ch86zO*ELlkg-8q^l(2>gFHO+1Rasa_P+XcL7cR$&)6 z$EG)~?8-V;3y)-{mLfn73?%G?E?5Ho@f4qz4AKK7Xcl}qB54YR332z2OL`~>B6rUp z@X#VsZi^WiF7O`Cs(LU8vI9#q4bq#Ag7R;i&wweAw}y6A18`iv+j=ANj%U2Z!08Y^_1kT!jNA>D#zvep_Mq z*K7a|-2>Cb6(DN%k2vRT$QPI-owW>_wM;GucOfJw$MV!XXL5sp%IFwZ@AFR{hA18tCX~HI$Du2|E zKY1LZ&b8RYGti%Qi>0m~^Po&k4R5j*2BJH8SSJ)Z>vdpj`?ya0K>Un8+cZw42lii@ zE6qbeIO}-|)pI{?s`T6)p%@4x!2X2%ACacspPiplCTB(^%ZO%-5q`zHhRMe`UZr&U z&w}|yrGRFn{YIp7TErpPd7DrfuOtGVB^+kQKAbhZR75 z#^s)%sk_qYG>h_SsM9#jiSASTD)uca1Nx;-f+zY{>9*a?pyH>wU|2Kto92WY_O{E> zdwm||!4Hg=NY-Z@%6LXY!ovQ3FU<|=yzy^&^fyQCYYCK5*+{FWt4bQK7opYe==J+L zpIf)r@morbx!2X?qg|^@&Z_Lsf$*vo(x*+DuKD`w-7Qj@?31_X=G@lLgPmw>^KGNw zarfMPdswL6=F0or?yK)(%sY(O>5kvp^9h<}r`Ss#*Oex>+tJcy+}F!fmWy2VV%sQ3 zY2{0a8k@oSXqsFvZ`bANtocZ{AE!nt`^!LwpV>f5>ix>+4bQLdag5&2#)6H55(#W1iQ^!uPMe_i2z7jncP_9f(~QdxK)-`{bY!!Bfm^&*s~TQEh71W8`mGQTHyF zU)@n<+UrXW*W1-;+v?$JY;S}8Ie2d+dQRT&Y^IRZulrHU6M2GatiBG4cUC7$KyN>h{Fy0Xe zOVXr?;Kug#b#YTN7jl_nXZOWi19lh2gkn@yhCy|t@xQ4-ufAZXiFYK4;uZCVK9~Xj z8n1!1#6(v^TBEJeGYwKdknPGA4xvK30c&fS>=z?;S=%_c8Ckm=Li_(QK3`m%UEJ+t zY_}L~Wm9b*Tw%$7u03{~?ogqI%+eG2#p(vdY_fCHRm!Bu_Pewr_QZ9JC5pKbr@#|r zju{nPLeC$qrx#Xt-@B)5`&9q;-{eW9BLGCo9?(lH?&u>cZSh0I@hZfkwOzi(SXECRDr}wg5aD0KU zhhq1DU+BEyaeG2<5?{!^n0_#LgO6|IzNmcRczv8R2k5Hx154k0vHW{}|J8K`2_W&{ z|Bz*M|Bz+m|F^C)vp4*&whK{%vqxUW*zMjv+UeX1nZ6F;7aR-a`U#HT+Q|zh0$c~7 zOM@T=?60qO+&X@7%+kKGeR+XbrY6LhqhwT?x7|GFx52TwhGuM9w6GZFQ@&I$R;^Uk zA}?B$y>^zbRI1K-@#>_r&(GPJO8ee<{WpHQuV7T;e#lR1NvB0Abpa<=9pa-L; z7MGnRpAvgu?U`CVQr49(viWhix)VmL%4^OR$ZQLB&@ znJU~$)60*RiT4SlSt_rG;1$OoV*fabQR=lLs@50-hMLOYBVrg>s_^7dN^^2@U7D+U zu&BUap+juI7Sk4;s0hhalt*M2v0pdTYZ7Q3Ia&4`6?3epcj9Q)vuZ7wDT?w?fq%>4$9n+>pGiI7>xe_A{3#w){IZmRH zDZYnBXUeENh%y$X!a%8u3E`7wmpf+=kIJDm2PPROtS-ua&2UqHI~P!tW5yBU_cb5Ayd4wi{n~LK$ zxg`nRM|dG!1A~&dMuYwfrwq3yxxpU&Z&m=y=jdu*H%$`fve^P zZv9bp8JV8VO?hKbmskqCDsv3-4{0WN7BF-a<`y(?4%57Mnf>3I6Npny({(XjBo^RO zA^ilM^5en?P0?c`>cAsZ{|cxUHp&PGbFNIQLREN|NovcAv;qJ?BpPSPGVxr%F{D%* zS03-+#*6--5n;q|Ejl!@iW)}CMpa&tdYlFdz>aN-91_2f$DG{v?8@bpE5K<&sm8Gd zW~3N7>pKnHFWK`0%31E3*~I~gAZ#L7$H3mjMM7M)uY6c`P-2Kk_)~0cZh$1fq!jie zK76gB5Y(h~L8+>J!AE_pwU>$b2k&sBbRz{OcamAuJCLF<)O2%-0VIR$^-o5y1uN;I`1X*8$e2KuiUoZd!=jR|DE&gu1B}Lz1*>Wt5g>PNEO) zf88|U1^E<|9~Uzb{|=c1c+F{Un+9~wPy`gX;=HN2hD7W|9TMzK9T+S;H)Jp;#2}aM zH2DB93c5$E6{Z_JxFuSPmX{apORQgFgJU3oc)&gC0eS}?>uKDkHntzpR{)+Rq|b!; z_@r&K2*tX|H(TnWq`Y|*;Yqk;N~cY&&je_ri}5(bo(^7j-syb!Ch-rm+lm7Z;t8js z6(z#cJ+wrLR1Ksw2(PPGePv;&(8~cEh)~zfd7`0YgJt_LsG2Z4Pz_7=z@+;zrlNOk zBD1tO8?p5q+7t3+gponfpG0C!6psV}$l*^P5A_#p3|JX%2za{uqn8-y-Jd0B;Mu(NpBdF*|8$=3J}O^QS3>z}5P5E7 z>i3Jz+abUt{!IqR+wiExW`~LHBZ?Y*xq^qYGtDl?%z23yZ-`e<_PX`*(rEYdlS0<9 zv-NcGu{TiGK9lZEGVf#pMYb=2#6VdUoJc~?+o*q#(b{&iF76?TdGz2E;L_w%wQhnM?d z$az-;wac~ov{0@`XSYZf4a?myo8qvA`Eht~daGa9d-wGq==$ySo4HlORNM9a)TvjS z?ei1JrD>lz^Y$aNE+^_p^xDhL`VE1Wp2W^Z-(7T@5s*d)mdgB7@%v_{OP39iW03g` zuJ^wGooD-Qb;EL;isZf;0C;$fHK64~*Xwx`lcv|}^tMyYw|@3>bM57IgZn%CKDGa3 zQ{5Z&bv}q@7iaf*HjucuKI*0WslON`lTsg>*3$KIc$(||6S33!&0Sq>LSU`EG(43k{t#HEkU$(^>HLN=C7G-%H?0cxcHpRSde=W{sc z^=tj{Gx!=y_qg3{Z)v$LP5{-x3pI<>g|su(Y*-)-LO$qTwd(e^l#wBE-U*Sv;+v9d z>dsP)5+1xCxqFket_0VZb|ihOf(4XdLVYlBfXu`ykcE5N~MGTbe+JPH5Ctb}wO z>k<|b&DMm$qLvjpd94juhFW}~bfY{aS*TrghIGN)$l8X|lQ7Y5Eh|&mfk3RM)ZdUf z3sxOhtgn#=@l$KJYWsGO9%vw*2D1!*dJo4P ztq0|H#BGo3UiTkXH>~%c$OL}F{ZjG9;|*6kASe3nJ#@p^K@h)BmR?RsH_QDfByai@06qb-%}W$kH|>1BpJAIsgGK>L5mEi^jtRU5Qm3 zjh($m_{`3=5ihkg%;97pt}rj$mbD?{M3Ko_iji1mwQ!yQYpP_euKG0cvqm)6MEF}( zlp@b%qxkA`Dg|M^DEsl@v-|q_{^P#;>N9Ki8W0o&@eX+yQSW24?D&UZRX13^Yk8>w zgNes1wer}SCa<=*Y_f!-`)`K3s@C0BS`=$%)p4b%jMbP~Bucda({w|7sp2$xdvu1> zrjnwY7WJ$?zMYS1<;Ae15UCbxrS7Pf!X$c3rp6RHQ;mHaE^Rf|JEPuQq!Ucb&h-$n zbgrpmny&3s+O%S6hpoziCunMc3UkrL@9gp2;&JwheM7z++TF~VY@Pz^!bX>F`NatI zxMhYSCmeaeH+n`QsWDRurxJZs%S4(VXLsOXT$;-uRH8|>xw)n-NqSa9q^ByiDdnCrn16 zuDIHHFk2Z)v*k9h3L zvX;n7GJr!nhtzsdyV6SbV~4NKu`yVVLJKTvpQK?gC5M7@hmZNDyO_m~;*R9Uw~B(!NgW zT>qqD7NM(9WBB$QjiH(9)j_ZDOi+>hS>fCkeZRjvQ(gVCPSP0}u|<7O4s|sBFvvtW?-(nkW9ixB>Lw>^1a2pxHLjQCanJ zrAFxBYZUOT|BtS73JxvWx^!$iIk9$Xv;09%4(f40sM(6*dPU zzkGv@?D|Q`VK^9T!!iu?@to&j1W=NX(V+Rz{+VWlo{yld%LI{1W0Xn|w2)iCYY;$t zOUqUY$wvC?)BT0h!!r_Ffj6HJI7uF7tlJb5_$Q|)7gD95+l@MDU}tAIl!^24^fGm& zq1*H(Dv51;T#yWPY)7|)g?_MFGE3U6-5Bcy{HE3;utCS&`w6NlqTWyH%rQsNt`QfX zN1OvgOnh7EJK`#dJ%l72qckOONuNnQRd=)IC8Wqj6De;yBIg10R&rh z&vuV+BR;utVPq32oSRw@!_H~{Ij__f%DY+ydvn`aV3K1|qiw{^1FAA|th3$ndhACP zesg}iRr2#WQPh%L%pY|zBe})qaMYsGz3A}_zrFID<8ftwxLRUE+xe|$`q;pcz~gEd!@cm85`E>cbyh|*BV^6vabMN5p8(vVEtU1<#A$bbMHcPNc0WGY z6(iDh^L03vgC6a;WA1VA%;K~IE|p^IzB}KsIn#Rc`AXDawfB6adC~bY&+on;Py1Z; zG81HQ^G);I=^@sBH}{klUA5EY)P3Wj^SThhvSa%8QDO7_a97ZC=85QYcQK^GeNf${ zh`pncZG6FV@+h%ccBUM{TGCtqH}foN=h}SoB~8QO%MUl>PT5)x-j0*~ly!Lvm@6If z0?fqm!H1Kz)nc$zKBn(kH5v=50=I{ZI*^TlQpD3~|2%ty*Y$lkltG*McE<62FhWKe z#d+$y>YBZ`b&EDXAshr5h>djRV%RQEl|+9G1k9Lhq2vlNMW{V-4whj1PHlfN>{yq) zU>~{|nVG!uTOW~5tJ~{0$l&d2e^dRKH|7$Bc`Ojj0kGv*DIAI|)V19f73}eCJ0%dQjmmM#X51 zXsh=xMDCFzOr`!0uL;k6E}RYLE63&m z(3JyM#9&Q43Dt+T5;>UR^gBh9d&9dvO)!){c#OF|fRkU5UU+zncufW_cHj`gEt8Wk zI-YDyfmn*3Si)YA$W0!P;o|J4z?X`|guV{iDcNeFe+lq$otEc9ylOhhDc{-|vW+OM9As-f zU#@AntQ34~rEQSdPaoSl^t@fae086E$rm^H(2dev?=43sZ==z0P19|%2kR{pDTN6y z-ae;-ev{0*5t%u0=Kn6>*KNh)9wc7<)1WRBl=r7#i5I2ZgQSU@TwlDaW!IM~6rNwM z5~oi{5e-QQE2T*rHCOu(rO!7LAMfTulQwCz>@LHRC=o^~*euOIDnq8AGmoH}3zM_V zCS54NuH>xEqoB-DiWipz&bxJG&o;4UE%^Nn0ENNds~{YM1eGb=9~UJo8my{w)Z9x_ zbmmtApg~gEcgtmrQ?v{(FJ9_YOn>DWU^Ed%3@cWOilJH;(qITZXOx=Thh&NfwWp-7 zR&6Olrr>b%_r*aciA9nsgpi9>Y7CQ1ZA}O>)j+&ULSRLT`6CE|1d}bpqb<=7%*BBi zsfBZb&+%6G=o)OuktMEe@F$G8Av^#(hIC<0RG!g5cF~Yp5_HK^YRr5=M!LX!5pp0D zl{cWd6bWXFwR z8vh9abTNpoUiu*Jkn~TqHnK7)QzKJ6)3iw{l-@kOvk^UT*o=MLA`^p{Dx1mQoyK6E z(?4mVZ$RCj5RI0qL^#Py_wPyAiw_#M>mbfLhJ1zx1T(ICNGo-%)t`ceGgAm+FIj zK{kde&QpSSz-^jZ;P+%D><*!v`c}oTsl!~+%zS%l7Jgw#KC&Br=v!8Yydcr^+QA)AaWx5I=sel z3L@65NF-=&_atJ+oAsl7yzJ?q+B3;j`IByjEqhF(zT1|BxVmu}@S=cg3V$Q4V{gd8 zH>7pe-_oXsLMt#>izR($WNaZmxLv2RVC{d9>((MH>_j~gBaU6)^kYyj zTS4N4gbv5#C`Bbhk_-)bRLS|~aeHaNW|y!dj?YbTS>>l|O9P2f*a4k#)V1CI0l1*u3PyNy0><>eDx>9un8Do40KT zs{Csx7nD*Hh$1wFLPIRWM!^oo?K+8~1VmofEGlxOYemr7gdty807W$bepIb63xn!x z#`A^-=k`XTsVD+{HTmzsG|#Sami69VjwqG{AKEIW)0X$Sh`k)-v--$XnJFw1Q( zhfNS$_B48gkJbntn*ifq4IMk=J5~u+T;W#}kiV!!9iCEyT=3*Mx~_jDNZS)RfaMvX zwOf$U;RJwPT?Y*zeJ&PTNInXwOK?D0fH10#(^TIfY>jRt^Xo0d31nLN>TvhwtKTLT z=E7Mfc%?;~t7xbx!lxd#@rgJgupnw>^Dy!DJ1765=7wW7(c&%Ejb>`8hn*T>G<`j^ zstepxfinm+ahP~_vkuGK*;*gj)vZ%zsqeASCGMpxQN zONr3CY7`crkvrC<=l~kDWH~fnlrBjgii;YC+C(N4=lDmP5nti5&|d)Utmp2Os4jwN z#}iip;MdoHc-6C9l;XrM!%Y!_zZzG^9b`ZoCD~veZm2FI?Q0BqlJef~?(Jsx9bK;e zb6G6jdF$d$bYdo}tpcg?(@=5E8BI2ac1wY9{GL z96n47b{@>x2cZF*hF1&ui6H8DW(o`8(g&+;1Q#L~W(Y^xW`H{RZ7p5xhxBB4T9Y5` zu6G`*wo%29+X_XeJQ0gtEW`Vt+BkgJ?*=bN2S*IDP=n66R|qcsj`gZtYDr6W!~len z;>&-Iju7cWn0x^&-J|)NUPzA4NWR|v0`Qw(SO?sw2527&?s!uz z_aHnH^q<{GnC=P3Met;>yxWwCY%KXctiQCq12e~{vsbo^AkvnVCpDcI!UrUJ7%qe> zqe%qcQ2K_*o7B7*V1ZLlo~wcgRmN%;d6huP_=LV%TN zi8p~q`R)z6Q^kyN6ovOgwa4=AxRq~;Es^WQpW>z=KFNLMC5&-qqj5Hcj>wg$iy=w1=??mF4zDzf=z-Qn?Sa+>&XC3?($&fe z>AN*!bxoupI}&e#-7)u&)4b6+hd+tQ(PHwn$MmYssuibh@I{#BHef@(h<*6t9Hr4g z*UaKFD@&?b$YpxrzX!O?9ns{Y$(c{_u19RPj`R#o;*LO0i2>cA2NKp<9dz#f=%K(0 z{B!Y8uIxsiwMeK_)%mIuJz@Sv4cATkRpU@oi^K91gZd5o$8RslA)ZXmmg>g)TRKON z4ehJ<@}CoTo{rnTD;>11_DdU`Ejg492kFb*k3aDu>3@2Bc7Lk~bae7OqO+X2Iu92Q z7m8$>HKJ#lX*`;nz3N|zyG*h~g1O5pN?lK$ZP2|~+-FS4e5z`8?i?RJn&59f?Oi@| zB>a;GWP-QxevUV2pRv^*o~O?DfCcKh9B_Cx;?}(;R)%6mT-K+Tx9eBF-_mWazb;}{ zwqNa}e$s7xY7;jb$UY}{ytLenz4`2h-eojvIFw^Z#o=(zH(cNOev-5`W4|7B54)D# zE;lZwKd&D#kK4yrG`wrO?I%-6Jq&|y+1gTzGj01m z5{lUFsJK0uFZ)%F26(jDI|uJQ9RmrRaT1irv@DzS`U9amgGy>p1+iQpBcE-vd9h+ZDX#<<2hF}W=h?dGnEYS_ zh#;pcYALCpe(vb~+yZb-{()I;1~YHQ^wudVRkQVstP3hXuPBF{DJL0Ds&bRV;O~jq z6%{MQkH;%x@gFTFTTG=Ne*L_L-zYty zIeLK-2S6o1(Em9f&R|hooBEv%+amve+HdWREOne5%`6@MuQG$SMIOQY1*27J?G2D+ z@ur^aH2@M>=Fk{W2kcQ3m*S5n)msB9CP<#5LgVhg~-2k0WsiM|l!AGeip` zi4mb@F}~h85-J%RCd@6CPMtU)xY7U9bi|_}E>Ppnp}}~LGo?3KJs7stLqR_v`ITUi zYQ%(w<0T7X_hy0)!o+b{Vh(LvY;Yi~2~sBUVVc}3$&w{xP?*_=wuAF!ngnSrMP!$A zdydREd3N0>1AKVnC5dyAq$la__;!S8rrwi)regvmbB6W9(Sq%<9k`*Yp*l&)=n()Y zL}7AdcYmacLkh;s#vB=?hmKGRP&WW2k@`XOp^Jp>gCyr`HGdl(`S!^^WhKPt2 z3A5^B3KQ-Mk;lid(hM1mTg$R%rL3?y^xH>)P&m9pX4&*4Y+dg& z!J8O|E)nTIL8zii?~EB&Yq+g;<%6+t>cvDst2l%gPsCTa_mErE*d1$!l$&v$B$GVn zwt3-<;4(AZ{fY8^!uzmZIx9ZwFx zwb9xpS#*q>@kPh^XO@Dnt=)7`vTfy;BNB&SyD%VmI1hUM{^8b`AKMQkVt3S z-)qHZYD?{1?n4uL$R(!H*(5M(9Zf2TPKRC^J=mg;5YBNz-%<*pwV75%5GU^*uj_7x zlC~0PR_rRXqxe89ddq$^<>p|*ybocNf@d}GVFTMq!VRZt(veBn`Tj2S^g#!C_-A<#!~9z|LbqSHbdImTl3;!NSdCj<|G~+wKZwruLE}B3%B&f8j463N;llFIr02dB|sWzOc zs6tiXJvk)4w{V>RmzJavIe!tw;;^67w%{hnlPMM+B|@?hf_@30cL*eR;@+XXSHDhx z3l$-mw|rfnGDnt*O$)7;gsx;4-v2C~@KxQ`e=8z6y%f#=uU{@Vgn52Z?P$cFLHgGv zKLos3rbM3=g}jX420ijy?zyD}v=dsRyYI5< zIDf%mWx$q2zB{pY;NcTKP$K6EkUADbukvp*IMN#m1w}=4T z{#E_zt^ZJbcp)gP=ypYC`@@ONysKfPY0-it7XiIa2`4a7J{ac{!sjVM99xO|^N=Q* zrue}XNBD|s!}w$KVBrdVCi-ePwAfWHf4*#))jAYhOihPjg#n6%lBH?4 z&9@Ge_u3`|wE{b>k(~qpuVj1MeQUMN1M>Qu&OH4mD&`PeWm8H@lStKF#TZ2 zRp1a7x=|ifqkL0mCV8>A;9a@QynVlm(eP>SHVCCqU-RN(r!VHyaC!v`RF8G01u~~9 znSB>6vqBIH8l6G!&k>PL3M~AMYU_xnolQt?@^VGRI>8j44SWq6L4X$?pq~9xWN#Tk zfINAzmkr*&{O#rdmXOzc34p8YmmLJK(-6fff)1*UW#mDL8Dq?~DD>$Q`81^G;8MSP z6HNG)fWvA<=-4JP#0zV_wtw-bSDd$1z9Qv zU2u~o=+NZ3(x?=r@0Azc2r(kcVEbex4iGZlkvy6PyX!z4kh5q*=J>rd^cWYg!oI|@ zawb*g-p3xy-^I-5#Px%JpEB4qm-*Mh;)=oSNvl1rK$Bxw3~LPbC7WW0dy&U)q)1pt zY5k8=?Cv}UiBj6QrCGMU((rYJ>thABJ(s^jtTEGJQ`qdIo$=FZ?Z!!p*Le`B%3SO!7yc?8$Be)tqAMVuxpBLYtIC>th zZ+8lP=-KZN%On;Zi5YW~I7)Lmxax273^zZw=sFiJI2;YSCX|l5{q>LMEID5DJ=b;Z zBGX-O2OrtkoRpobi|t2UCptX0buW`MEUYrzo*!of9N&efPTv37l$U19WT#nx` zXTEI=_c{1|`LsW+kB#-tblOx{TtFYV5L0HCdA!eVouSew;RS6-f0pj4tGxu}Y;OEY zsJZSYA0wLO*{8FhIq9Pd-Nre#vjYIF6VjWk;+u-5m@#oqg3AK-!QgahnM1&cwz{(ZkYRA9k4{KE(L6=1B>f3_FRi!CwR4kwiqU92o45lpu&K7G zvLU4B&Pin)9uL+t=s_KtYnwZpyEm;+68x(*IvfdET%@M}hy6!*I8u)&!v?YAB)#<8;K`jW;VD>N0^g)!-7X%uiHB;hXWg=VE}@yD5cHNuU1Uj5t>$5 zmtDH+!7W$d>yh6hs~dC2pU9OX`ruz?ZvtzO&460wfSYD-$1ScW$2Zt^Oixr#z|HW> z!Ob4tF43!=CkjunPdMJl$gQ2{Z+J1Me`eR@&f#_Ce`7wpF?0G%?$|s5f8c&_et>%- zczW^nsa|znkv%beqJI=7mhPLL*YDL8FM9C~eCW4-6i5a>;r~+!N!%56rlbEFQ@>fd z|H|6?RYHz7HkSWK2RW)jyP_<0?TlI0he(l58lxd?8#ucKk{H^dkAguYSTaXo;K%zS z1Wp;d#8a3WYFj_z5)v9n_hW0S6(VS*a8!{z5ol*OO+V6>NCWr z5Lvi$O>`Xn$A&36aWIk$oaRWJJ{~h1u*XY|YZ2pUi(}6odoBSwpC+itd{zls=13Rj z#I{C6=CH5TW>1ePbKC?@B*&In6Q&?^1h%n1=14GVu%}CpEqgX>1~TUg9-$X5Ak4U$ z@+W+}PnBQ^eD4u4n%FI>5y#%iZ|s`4o{NWCm{%A}g2}Q~N94^}| zvZS!Tl^k1u4#4|=2Wu_BC9)bF}b?Np1t#f6+hEu86)fm>@|u5B8vl!9FbOW!-56KuR3MrhdIpuAS!fW zZTXeV*)qa2EyrCmTEmkXxRuh3G6m~`+9Ub%+h-@Evx&L!gQ=1rg(hIb4I(!R5p0Ys z5H5HsFm&5W#=WzDQ^Kux7)$F`)%2+>99mG$R)|T#(qlE<6*w)0eWN5Lylvgt8Y==F zjk@P3dq<5zskkv3?(A2p%3f2?2+-#POH%fL%|W@id60tnV;=n^=Ao{bK$27ZjA)J& z53|;Bb`0k#YCPv>V8RIb@adeuuIKpM0U59lPOY3o;UTfkK?rn}B1=vB~DCIL`p5D~$M zD)ZI*ZI?G<2~8_lX_B{rj#(#ERt}lhQ9%|YR2XGWMB)CzA^t|VWZ4eZO+V+(%fLv7 z#bIBp0&bg?qO1M*?r0H1N)jc0tYW7)3dVkdZNwVJdXG^Ok&4Mn`;GKAQcj~%C&*&m z_2{r=DHt9L85jDZlPs5J=1Fr+DsxqqJMtCbW2%iADQbsgHMo)K&_a1H+a!WChoYw{ zjAMqfRcZQSM2u$64QUqZZ|hcUzmok6WC@Fcs!M%U9-C=^qM*ME`v)JXcziK#G}@Vq z0LV`kK4~-}QrWip7WdnXSK7KX>Cm~>uO{9`7z(=4g zO0kEjzvK%@870f1*R(nl3kj7LdPM;iEJ;m=QOJCWlJSZNt}^+qK_Z^nD-Ve%<5#Fk zkPykq;>N7f|Nb#D80D*9FDyq0TPpGQ$*!*0oi>Hp#dliICRH_7q06 znrPq1loIrxKcD5SP*g2dA&T&1fEEL)zQz>tq%p-{^w1ljfH69AzV;@PMoDa1C?h4% zQ+})(X|^h-CZ=MtTvDeJJx3k)p9>)*=%Shmn|-5nZo}v?UJzV@f;D6354D`wf%1nS z?+%&Y)g{6nREIq6#Lz9n#}+t9-F%=0n(7DH}6hClAt18^k?HA&HATk(z*GKiIIwZLyN9n@bO^6 zN6oJ4#a1$}yQp$JO@a1PEV2-x5zGkP!Yw_Z><6Phr6w0N^}fGBsfD8Q5Gu-zv8`b# z^Twh>9HUxW0|K?1Hu>QnWx57r4y|wa17)iS$U@eXl)JBL#yRkfK0)2dxXmSF0bF(UC1gc)pulAUNe*H9{@2Giw|lq5&5C{;6r76=d`v zSe;J51a&9y%8sw0v3iB9z z+H~1V4~I~*FBC9Sinm+1%1m5N#=6EEV_PrBH85r#p)?hTc00XC($w-ASvjppKinv0 z)GlP84h&4;86`v*e@xoS$E6JoO%5alwFWbzvFFCXH7vJW4t%WqSV)upb)on%^0aRH zCi(ucqh+fX%0f=88*j=3)0^35&Ow%t+l6Y%hP~)=&^#nX)lk&@UspfO2@= zC>*ORc>l7nuSf(38!~2H?E)2i#PW(|gl#Qzmwj@h72@(*KU6aoBhQ3RJt|SYruDD8 zTXK4OQC}^8exs*tw0XnZ$xjc|WUN9L#QHl-=;~X1Im*m9GYC z`amV9Bczo|1dNxRYpZkUb{dU48GEER1m==q7T~_ssV!u1qk%`G$?UjPzQfk}uJc}Y z)iOzt1WNGiyW*fcrT#jg)nq%iBT6F>gjuYRV_~9}eH)2J7BQpC>_?q@0)PY7Gfl24 z(Zw$$G?+EBAx*1|)2_~+9XSm8UacbF0>yF>qQiX9DO3$U@KF{TV}48m?0v}3An7`J ze|3?1vszu%Bq4n%Rb2@>P8e~DUvn9O9Q_N8PbDS&ys*zW=&{_k1JtUxZ>yxQ3+I#( zI@uU?4+pDX!_U@+xxZ_L@HcZVjSn-VQI{1}tc9`f#OU$`&Di0nA(CJ|%bu(PwZ@f< z)xo5(^jPE;aC?Qhv01`_HLXv@tm$vx%TZ4VSyc&T&vj=X-Dw(Zs_0Xze|C{{0VLlHt)-J zl)|m@6^i00pKtr>z|+9bx8=`A(+$ZN1U8s>5}b97_v%wX4Af=>&O5g3C=SAA%*85x zH&WvP>W%?(g}X<$0&FpqT$(%M94k)$3&Ku0&Nc6<3Cd!!W2mz$*3|&rWWm3wC3@U= zVMejXtnK>lpl_zia#sI8UP<9i5?xE>JdCjgp^r%LE%4Je(4ammUz|}EfTF%Shq^8i39@cl+we%i&#zq#1k0y2*P?N%)FeMV>rWr zW)5zx0?m{#aS7^0>KT0+76%!oHuiG|QukP1QoX%0$92p(DbMj8d+tr|VIe6VjT&n$ zP5HQaLR|T1PdMb~9GLbY?*~v_KyU@JH;db)4Z&9_3K>c*L4+FTD8ZxEG~&y z?^Z#XftLZQ?8zsG^ZqJWO|azX2trF9m1qqIerA^7b|*+=MQQa z4GqUe>|dHNB4{>k(gIgyvnPqhe%w8{14SD;VS95cXPx3Xw0)}O6NSw*3uhF<@!i@1 zaupYM`io~5iqSGUB@cfbwZ(hnQ+lurqND{*qTb)tBa5kf(x2Fde7ur%SWK#HW>i`3PgI;7Wha^scoEXn1BMU59S!(GfAv~vP03_S1J$?EVF zUtnwD&9B6q-ea_HBZvu*cEB2EUvQUe7#hqCHt*=k_`|I>_nSdc2-n0QUgO>2f^UwDIR68|1jqaX;Iyjv&+N_|bmb zjP^LZtN1$E#@nf{xa65Rtl{23a%Y~W=XpJW$K~>{xUHU=S$+;mr@hmWe6RBvnqFWL zQI>|pTW|UMJ~qRFzMON$+`XdVymB<36ZgZ!-Sc^wG$B)&`N4N|!{Uj9jcuydu%5HC z^mxUT!{T$EerDD6vst~|bE#!+vySNYzV*?}-FmuM#FLGUi1s4+@jf9ccjtA|iFe(3 zl+}OJ_3v{sdM)iiVx9E6jB5WaEdF)Cu6b-dR=vadl?Tpw$L)p#v}g78sH>xA&3<6A z!A%C+v%dBI%K_fGv+;YXw&wYu^li|lO{FB~?V%vV+J(#KxJ>2SvG@ht#)b1|RCpp- z0vNCBr@wp0^F{0><1*-hN`w3J?bSsBFURF&aiQiW?O{UygTcp|+~dxeG>bON=kRJq z=j*u2#$JZ|Zja0((Boqg{RbiKXM}0W1@C>|b8hFF`~7Lu<#;A+I`d;}jg6*xW=DS8`BZvIo_oe6{ zuw$VS6)&3u99qxX$C?wLq0F4tivyXTj|3C@FDa7}OfnTZzEm#5J$j~v>#l~3{4tNbOC32q+8`|e<&xe%R8&nOSi z?Q0!!9CU4}4OUv0wa+0`s|v!f7mNLx&2yX8`}N4^0So3G*TU78Q?(g}gpi!C*Y6!| z&o`=-F^USLoMc7M#U4BMF)hbewvjqaP;l=a-SoYnb0Tz=%grW}doQjT7L#xW7iqfe z7#sJ?3WK=QLMj^^p4z9X7mpF1x;=prgFa{(ZJwcbwx6#bi?o;hftM9dm)9@M8Les5 z94%C6sqe9Y@!Q0K;25tM70*Q02ZM(s@R&>PX42P|N0;d?+q1zU36;NEYH|yYKR~}b z_CG&Xv0A1mD%e9dlgxLk%2iSkiW*+BlYPb}E?bKr`zrDU63oI@gzvg5U#U(eE)2-V z#sN&BLy8r`Kpm9<)}L4g#M-!NaSZojwT-J%UN&Pm%L~2 zAe!|ZN>zSQh-!u)O1&y=aLhKHss(n6$5RLOAfIYgaR4-HIxsRW%xUo3%U>pog9B)1pIuiaD*U%J2D_y_jo?K=%4XwQaE3r7P^ z1u8mQs~;bUJ=bdt7ZF3vfmtbB2Gn>^_f66{Hf+u47zYmLMhi|jEJsT29t+pte7VDA zuWS=EWwB{>m%U~6;^oWr4M*bBlN5@VnQ1MS3@@F36(yuIA*;B;4m--O1yAPV(@`P> z{}4^p6)Q60MllWN1P#}idC(@Q&TT8nubRFw80@+9&-t))w5yy?r7z75FOPQauXcP$ ztt5n`EJEMeDzKut66~BaK{H_%nd245WoKundQ)sMK10rwwW>7~?hD6|1qpZS8cVLQ z)Jsn@ayDeLXfh-?!_G{77sywuJ>!&MGjG|;(Turz&wdtuO1-D3{6ul|@8#|((4oVI z;s*;e7Jx>~g)=uAupyoDB4w%i{jKbC?~LJgE!9N^tA!1Cg%DT`(7PN$#2&KC>=n!G zQ_CCyjof#L-2J0D(9#{lyj!{+0-LADnX-`O`n=?$38`j_Wvrh3bS_ zW-mHhTup7X!W*fHE&EArHY_8CUZfqf9e2iBKd9#5?;wWWxi+GrE&3wu7|b~J$oYDA zWOGdGGf-f2Uxirtd2l;29tiZea>KTfm)gzV?cm_ppuA&^MR_TCm`VQ z(%e~=sp+ZgnCJuHT9?e2E0`^g^MhI6L(b`oj0x*wk37~Am(2@i z8ImqCC8>5LEDvW_-Cx&TH&-1CRwLDZVBz&QmR2@rR&$9MLUS>)C`t;s;(fm7Dn(or zYDu3S33eKyVI+s8i6lk)^~OmDh(qk8Ldda^pN58UNtdDd!$9iVrjk%nuP@@}^2+;T zm7@6RiI>RniMKJ7_MVI^I9!E;MEB&_NsK?lm>Nt>Bu1eA;pKK|lkw#wV(z|bzs6{D zp)l~>T;`#oe1g6=VQ;=Tuhfv09cT%Blu?n-fIJ-&)WTT)IC<~r42W_gNLYqIC8bai zulzoP#Xq)ewU9Db)$ma}iplh~FLg@9r27JU`3DQA>1wfp_;h4wNl=m=0&WR;C7~$^ zb3a$s+~BWaMlu?rqOmzcX-UYE{P;Z1oWveuX*nx#)qHZQL9gA?$07sEeqY8C2ee;o zHT2r%L}Mv5nn(dJ5&hYUP(*=Ju1GVCAD~_6P9J=mtWx(E zW}xYG=_^7|#CQLVS>?=QGz05@2(5^}R=K2$3qR$$vC5!Gn_2f=J4w8Rw%qe7$+f<}Igvw=eS46;Ho zS*ThG!v!^52mZXITQzxn$*`5swuJQ{@L^Xp9#hG5;=!_|36(9Pzg+Dv@lJX7YG|r* z*V@iwz1GUY?BO+i?Wr40hkR`iO6(AjT#<{)mc3znI4ahwZl9*HxJ1=0q}QWL`w|Ea z&c&UpdyIuj{*^nctW^q7J6)DsvaDClZ)=EP{Ioi0v2*;Oij?U93xqm3QK^jKwW|SH zC23SSKBRm;XuAG7!;)#LHEtuob<>DtTXnv8oI5c$&0M}AVQnxCd@Fz&|dcPanWRQ#aZT zh72r9E>zC&UE<&PvMr^Q^svp)s&AalFj*#6LIS47IvFe%7seXKpQ$Hx2gx*Lx`)IJ zI~r2F)Pu+w-k8e0RL1JL`|ZO95$>H2w%J~sH{+{a`8^T5MniPLAIpr4jz`nw19Wts zx>NRtevcgrkEWNb^N?@n=QEk-#Y)c4^Nkpusjut)MIE1HjW>QOhNqxQA2ct|*$y}B z_wGH0r0!_Xl>nYAPi|DUa@_MnnT4Ofh(5pI2@hHwWe#tz@9cV(AoLQX6-sAsGh3z1 zPd(eWqS1L#7yE?(6Jwp1+LP|jf;EL3PCD=yyh$VUnUs@BMtHndYN^kEF9lvcr>bi2 z*Hq{k=}_V^Ps+w#8r)uvJ0C2bFVogpoTLsa$vIxflP@RI+FthU=Wip?wR1L~2h}~3 zpCYVmx7IJpLoZ@`Q!F-H@2^$JI%(W?x;^Xfd(9D9FW+V}A461GA{;s4t}k63^WHt2 zkLoUC$v8Ectl#pthkNJ}BV@xfTq&;lo<9m#Iu9ViaLb*~%li}E&^)Y<$UPn7UACqR zPd-bM0XIQaFPxs&!)N_e*ZmsXQ!0T*I?J|e=rVp}HD0YZi!IJNs~-|>2X~wku}wFh zyGz>w0e`kt+wLmX+iUQ;Khvmide~+Q0>P%TSixpqSs{X`_QBmAb;k_)o>aD zDSUYfhl!`$kp4}i~Q ziuLP!*@Yn1#KoZ}&OwZl{OvPcP2K$K$L?eqQIq=@uWFvx?=X5fFY8+1oSrsM@Gj4- za&qtg3 zx(~x{9V6=bkDHfUR9g^pSCEbr)?MOztJQ$&>T2QB#{My74i}}QU?P^1oq7@w^EB`> zl!V%UkoJPW12|8RXOy?e#5_+hFa7qJHgI}HV3ckGNx)ir#MQ)O#&Y^7XYml^*ww1V zwGQCem0kty(8Ie7f$t?a4FJ9+V1*f=1NgFK!45L8#U9p0DYu2s^k29|WCe!rAGn2N z6-oNkLHz;!&nujqz&(Zy3;>|@x5eVmf4jmROpPr6$CbBIwz0$>Le1$~d-xv9V(50- zXKhQB!iKoBbMY7k{FCl{H3%{ytxp2yqd4g9#qn%qZS%t3aiWXTi&O-~pX<3h0fdAI z0m2Uf4(Z3sPeATD3T_CA(3o$95@;F+K(th<^pR(C!+fOvRJb#l!D8cmGc$eN!4Zv1 zML=8~85M(z3)_jszljb(U+Bgfy;iNa7D?-YmLxere{L-6 z77MQ$;4FKbdhM@hqMi26{qz*Dahor3( zSqU3KL;BTg2ngq2gkm&l5PU#GEt`BVljc;Q-<~XxX4>)4YymDY)>|!?{D>od!AZ`A zt6xoKS!1wmz{GHB+;~hQUoeD{b1aiKnWXLp$Oa|~y~uP*=oBCw!H%*YZj~^VPu zZ~y$BFaa&urcKsvENN)b6%UrqfC07I)A6ic6(`&rz^1^y@L$+JAT14mZq1Itzz11?VJ1N+wa(NQi+7v>j?xgfWN$i3^=e$e+(kz<6m+;h5-Hs?655B9IPT94eZw_Tezie$G?J+#4Jj+aZdi zNP})J2TkxA&YDaD5MgEFIR@Md$Q=(kVUh!G8~07l#BG25ZBz^XWbpb+yLPw|=J}x* zgUzY~?YvfXd;?Ws!kxf^BubNNl3!%F=lq6W7gmnE_{DW2*D5Sltcl9OV0YdlYvt|% zU`812p>P%Mln)>|0QBxbM>>cTK_a&Q6)X&<29AjKUXa?Uatc@DLb03KX-$!Yh@2DI`0&YoIUZ|4;?+a*cVg3CZNaF z&69$f?f1&>QA@h+?Y7y!*>EeHN0J}Oywlsy*RPU0!6&>O*DpP7oAyT>PgijZn*%%2 z-avq|?nlp^5BA&Y{MA<+SK&vrz0GRd^q3&f#~--P`IJhCsQnS$STyV@xioND-6z8> zu6!D#J-D$yZ63EqMzi{?{^29#r@`W)U%u_<#7rlP7_%(r=XB+@v%n@oHKnNII#(%V zFS4x5<*3NT|z67gB{O!Y^2ef_Ko3% zpj>j`P%X$3KWp5aOgOeK*i=_I3pO^zwA2d6Lc7X|*p$#{U_>~0&P5U<*n<5z(qoh9 zStjGyHl%x=Fe=5$%xc_#QDH6gbJz5+g+zXMs*F zPBlux<3D$S{|!@+Qq#;B0}23e`upSfKPJH(oehl49sXY<##&j{YC{R#XWG${%esAq z-TD^0puV05-iRcK zV+b52nbwH3jt;Je4WC5XXPjOvE+r<`+i*~A+&_=zbMt>;n=eDQRvx6V01ZhJF`3wP zkB|V!2=FlI4mykuCN#QA&64vSN01XD$+HfyHElN3ry9Rp zNbHJoG~y&}l|=&q#&9Wdd1K`Xg*4kM%vZ_-NyUxvJ`9;iSq&9`dS@|l42m|7d4m!*@Z+bm`(DD3v8+%(MnYk))mxVg~&Fb1~71AXd9u0}S!GV72Kjlvk zB)-PYfo=1%lKGtgEc9TsSV({de_u?Q%M6ppgxXAnaq7zrqPNU={M*KsFXOy%CIloL z1Twq9X5%zn9rzSZ=k8iNc;}XhC;<<gF`yIeWbnV5pd^y;VrRseD-{8mgW36 zJ@rs~(zDS(Bn#egZ)aRtJax5y_3#YJQytU&9K>Cu27AI7_i;k2>%q6}ASwI^e$em7 zR^M>Z@X@TIs*16fky77h*rObEJEJ;`hrRyu5f*nw*K^%|uwezl*4_2&?y{fBxcIlJ z^IiM4YmaKe$2#z}q^}}pGu_MW%=^8BXh*Xpc;@H+^f)c7c&(@pN)gI5d77Fh>&@}| zY66aSyzKJ{n67+33%pg+>iuqfXN2!-Pc;9+W~IyrHDep_UyMwp>=`K8NFiHFsjBXY zBa5?#GbfY9i<8Y@J#>lbO*w4+E)`I#k;S#3&~D6HOmFM!(m)2*L-2{%N2J zVRPz42@Y?8DvijB6u4dl{;oId*pNb**sy!ZZ0QR1eGwh7#xzxWfSd#deYlF8rAXVK z*7RRTP&g@?>jhNo?Vo+wtn5_IxQq<;G}-_j2nJq!SQ0SDJ0os}*iF(p+vw?IQkf{} z6hO8bHNpHFG2PEJdk@+R3@p=qV2V1QxhYR^R;hS53})gFun$C7QB4UE9ka;4{(zs@NFM$;2gv$*wkoV)@Xo6Pqg{*F8e? zv5aKL(qb{|!z56y868_*rC6>(oMWA1ojs3M^pxHAHsTjdw#g~GhE4lxXPdx`L&n@I zAEM9y(r)aXVr>0J1pufd`d`|OPR7=DR{BoH4*xOyi~LRXDlKK@aJ`T^q96B4UkBd) zvD5Eo0wGQFBj!Im9J+;ufGF*ZADjFI;G|)gk`l-x)9;b27o+r5vP*i`(XnQywv zPgJqI(Aco)Sl4L0IB97ra!P9Mu(|l2&f+>Wxbn`p;c7d%^ZERadEh&lym!8kv|^n( zJ8v&5)`%Hdj2( z%v0)ovHjp#j2g?s)1Tt6hUr)-);PBII=?3|CThWYG&N0JD2Zsv&|@*-)>x&UCUqR< z5|lLle82it-*qAB)gRJ)WRmCLR~~aZN(I5qL{u6K3E}-RR9c!d`o9IO>E6}x z+iEe+Asv5r_)#Geq@3&Y3Oosz>3NVBkLiqRk#OGq#vMH>|BXlc?DJz{C{Q7u#Y z>&Rykcwrd-+EWU(mjP33A6!DfHrglVB|82k1hU2s4EPbM=7JI8^5_VFAUk{}h4w5| z%2#z9iSrg4N)}@dvnNLZWLCcj(NtK6Q51S_MQqwGNeB2 zGAgP@I2YX`bVTCTLnXWy*u9bc5l@+EKgNhe z@(-OcBDIuWe9~V~y|pywce<4aS(BouUWv%l9e$BLw8CT2G@_z-6_+u-ZRy~ysh%*3 z9JbV&RwKuE5UYH;Fe64e#bV^{y9WTT>*UsjvB#GbM1``FfvRh(P?2GkcTUQo?!IDWb4l9pkTQ1^5QPOPe2lihWZQUN4*{@g4TWd_%%n zoqn7$f46W3;&;f<(GN6`FO%req>O(Mc?S`>HO#()p3}!ZgC4^+jK+X#8cBwJu);9S zHjL!Vh&xUu@K(rRpKEJkphkuic{_i$Z@|pd>kZP{Jk5uw#~AmwRbAhkVWcKO-0rO( z@*FVcuTo#GZ{L80$T5WxE3-OI4Hw^?E{|qp)x303w}lM zGDxFJ$C=jX1|doDGTi1!Jez}%6zB^>7K zGLp8lIMZMtM^79~CC_DH@*KZ|so17iQXJnHs`7&@6j03|}Wf3rW(a=D1t}st>Q`=_GXBJ19eh0z!Cl zsEW>-o)sb+bis3RX{T^15h+SWhTh_TU{l7u@iGcJ@QY5r;^@RH3Y_5YI#vSa6l5CX z797TLjgDjU$u zs2PfGlKOt5seet&W}#gUKcY&a-G zzXAufK|`Y65j#968WA9grRBVfs4HI}57Z#(D{FUgQpY-EQHN|>)bLYwHfFAD-g^nB z)4EI-OM=v|l6bo3-M_Z-c@gpziuIPNB!xN^vCJp+9*dXEBBo45bjzsp<{VI+D$LS0 z&C}wHg%{=StII?5eR@X7r~oO@Xw_9_s-#ux*@0qlymTfmwH~T?%di+vQ~XMX&mAZN5VN23lf&(G{I#TlNUILhB}qQXW;0VV)|)9oVnYU zdk>H%Ee5HMF}vOW%BU-oS#m^5wT%lh_>(w$YXH+Zh)g&uz=;6vLM6_j5SlhW+^1a? zRe;nR5NOj9dOFp^c4xR5qWG&2$g7+e`Z)q0mordiUYY=%3lcdvDS%odr-U~$kGT5%+>>}u4(x7>583#~@W zvW%px&mJuVn0)fW?UU!>L(@pNi%nwIqUNGk@B(p}gZJYA&qBV!?A*K;*h(+6s3lleGwZda!@8 z9tuYfYF8sOB4|FltTKXX8sK(q;ov8PpQ>b*0kz?*0A^YB?=KRzOLJ=qvlXSViBCs; zjy`QLf#dOgvT-dgOSG%wXV~auL^jdDdW)=0LMCMj3Z1JI=4c4C^iHByd}vUgl;`Ap z89|n|9qT&jU%?2Gs-@C*rA8J)N`oHQx0T zU}g{(Cg6+N4CEoxmb_3ZOE}c}UyIX9&-1)hQ7&~d_nY^_>@bjZ408w;l>q z?&k|_WVI~7`ZYEPkYN4I;OErpn4z!3NL32TLR1$skhW1#9Id_MW*;1|qAyBdUFDAQ z*`0-4hgi62NcYYedaTudXV!!3d)xv#8*Fz=e*0Hh8@yx?!&-;TY8lFcRYFBhh*7#E z{T+VTezhs+nWVg9*egqMxw+Ge3(dqZlt_>j z=;!4DdIfYCpfU>1ak$KUm`J`1gHc-o+zhr_I-#A5FrzZh1u{=FLPu*l=IiLVtF)`t ztCKS6Rx{$fPk4`@Bj^s-||Vj1vM=G*U=Uh%yI!t5y~BW~s&$p1H^1`X>eDx(*2_%qFF^Cj{WT7BF+APX=H_ zW727|Z6=%yyPz=j&xmlYg(zs$0K-RB^x98abQ<8>#zJ&hfG9UrESC+W`6{9UJP9;> zu%?W7&KX9Q6NXJ(?V1~2^xlda!@rW7xlSoV2#fgcA=z3 zRebSB_gR-e#7{r`@J;xk-jD*5{JVeU_R~x=!$`7+=fSBxtJIz`)t-SO_&wYSFa$^8 zg@xhmg+UNT?1lyY4;voX_+1W$QO0)2!@{}AS0mm^-xdqQ(}elGpSnD{)6XYBO>NXU$w9CwO8zbY5%a5o zMH4v)z4Ov@0XUJK$n*URb>yu~;OfHwF42*R+4C;nO}{IxN0)Xk+qM`Q#uKkC4b5Pg zG1S7k=?AT94do@|yczB6b`ea-o>MZId;HVGW&i_zS0L8)D0GsV!#lZzw=%XRm(yGK zohoVknHGSR1xIvNMC?Zp#Vdm&VYTKa^GQpc+9kF4?JXynyijRdZ{ZW~8%Bm3)D)6t=^7+HAtJ09$A^Q#S2EHuW8J#OG+bm(Bb>hn``5@-1-e zC3P$%ZAU*khxsk?jU^7*DJ-GqNQ7F zCDgM;>xJ*mHaO?&2r8q1uJdW*0rZV-i>LGQysf2un3v&u#&*%Qk*^vL&+KQacSE+5 zul72PZ3ow*#D4n~-21EaVF(U0`P!PwS|d(%y{+neVDRY!Nf~eRBPb6oh3e|B3ay*f z>9s!}=kv`DohvsLkIR|ST2FgUb&cm!_g@pQx6!fsGc=WD@DiPMB(ERU3DlVGfv;=3 z?TyPlpAA(fhm{xJb}HBJbtr|2{=R>3bP6&n3v=K-tt*c8jkN`DG<6QX#!=et`(Y_L z)0`eZe2F~`=W#E%RGnT9*C{*dcTWjZDL;>BzrKz-vKgP%+sVxv?6%Gq&4Leax04W4 z(r0gHcDJSEPrc*Gs}7e+a$SXwDK(X==$)88k@w!{OFr54FPe33=YgAU7wdONEYO{9 z)f`G%4{yt{vjnWq25{6*`%9mhNuG>9n3G#%;QCOPca%`9lLy7+&6SYI!1WwV_s{~gp9cRi-xSGb<6 zbwA20exyG&HIPL+R%W!^U*^SRPNaCfyco(7_dG}R$h;jq^vq-JI7hu7ditoT-4@kD zm23o`R3dg%cQ3q&PfJ$kacEBKJ|sn6<8i;d)9s`^1J4xDQNQVV8>cNJee}(AEA-eM z2i*HoW!)ls9()2?M@)p|Ri$gsC2^nk^+d`VvA zUUb(5p;;Wg2j&!wUo(>~nh`@$_6Nh+wyIqf5A1NxIw-wSOJKXnmpXc>#P`HI7=`(z9 z87Zz^A3EC^V>MEn-YbPMJwFWEhyq~+O6v>X{Z1OhKw2Pb)@3z|0Y-9K5(bP@z zk{BL4$&-x`m5`o)nrmdS+ItE&Dh$-Ih{o-^$^Ri3NuwuWA^KQ+JE zh2J!;bDX9avOM;1Oo~d+sR06rIy{fkPoTD|rYg;yxB1lKq$Hb`iEH%LrLl^sNmFPx zG9hDWV12JYe!f>IkY{OOzJGo$KIJI^Ql8kUs4L`oWEL$Q%x9`?_YGHwmsm!>EZ_{7AOXg@+_$s3b{Y2K>Fm$gm*-)=zEhw$*616BNfRrFNwdy85*QS zQ4Se-vL%ndSD7OyZ&?;l%_0Y5!;?eWnnxMF=5?C3iF$C>%kU+0W_f+1jbhIGY(uK; z{nBBpeK(zwoa?^AQ9NFpSdi`we41x@j?D`bVpekUtn|jH(wdYFIs}m(>4E*wsy-Ta zSYeTcXkyVrZt;dpII1y5I&L_Lay28dbCRnWr|Qqr9`hX1^y59MkG65{T2D3QxQVC3 zmU~-Jw!iPj#q*)NPYRcJz&mQR21u_y*-`lkC)8x@h_$@OtC z1uU-dLgzG4$;k6O4bAjGbna`LA!K6EIJI%G0=+W?QyjA(_qbOzsv@YG)GQrJty?EkvD&7c0}(310tHlhvRfUeJs-mW;qway%4Ks1FBIg)je3uL?~!g)SIyO`@KuXbLAQv&Wh5~sAO zS!(bpI!+1ic?qynESR}}vm)HpAXevqCieilsGOgKQXVFYT7*WW{=*N`OwNCf-K4;z znkD=i2-$x@?f>Hv)Y;C|LEp&uKL+R4YA{MzBU!rUpy_eyo%4{utgKLotoQ*Sh+u%x zDR2b6=%Ie>&m5?N8vLSWOG(0)q$vZ_B=*%VR~^GmE7l4v=IJT6ANTXbC&wf!Da_V7 znjc=~^OElhAzBV8hx4sAp9mc_u0Lzq`fm!`8ChvRFC(@ls*ljtHo2vUvZlF)ihniI zi^$u<^Go$bQOWup$P+T-2jt_j5Rvk+Wg?t8^~;8nhup{$qK6bE_Z8SN!^OhJR+Z)w zQ(=n+eixql>QaS5bE#UXLP6GL<4HqpsfpqUTn6kU{%#(a(!=`(gxpl=E)sRZ-Q*(! zVH5=u#^GY}2&GVYq~Mwo$%*!lW34g5|yxG^WCe)C?49#Y1lM=n3~^B<`%4 z&7*0;OZ_<4mcC7~(EdA+lw}HeZ5BdATCXklmBSjRL!-&evC~<~k%nB=V`V)b~MMA{kiJ}3EkqYC9 z+gZpDHZdffQK0GT*K2On42EHG@3O}G`W&{5*s@_J@dk&_r5r^wvp@zb)YlRddt#h? zkYyzz2_S2;u~It3w0_CkfJ{p2(0_{o2^!`z&$$zmMdFrT_T020U=m6+x&`GzgHc=F z3l*%e)u<|oDJy(!dRHZ$!Bq64nkBY- z(WW0DZI3B@kha!^AF`N-oaZZrcFp?wAheWn7s5v-8-REyg*gbMsr=JUK-)8@L#8T2 zP*wq~4}l7>t#Ooxrz-JhGvS>9@D`H_#~#x8_*=lt{EpP=Z-|b$%(pkhJv03cm2TI8 z*$tvy&lUm!YR{lNLlHX9q~XuXqu4`L%Z6MH2r;8_ z(*nLfN2;Ud@Ok!Sa>Kq>1Acceuqh(FpH*QO5crq5N(GFp(!RlRFAsun;S>#Jn+TEW0@NjU<6D{g>=vTTPOjmBM3R958mlSBAZl0e3jpCSkCzul8a0Gt|4HR>u6@vK{i1|p9 z%f?yHe(4w3ZdC{-jVptVN1rd{n!P`pk{8a5@FA%jKxM)-9iuIC+a6egfB2EcpAOcD zBaPmAla9l7Yf$G>kKB0(^O{?FXD6(wMHDDhs)O1}!%VP4xr-#_jycN}7@ZE~ny1|+ z-ixN}fWpl7gZa(E(YrsT=e4JEnH`~yDd(M#nKi7rlw0m+s+l(jdkPS=?>i&??&r$D zYEXccQ((2p3$RNTr?U?0$9_kcy?;1VmjECcSNLbfv?_9W89VT^y;E2G1?p=8_GAC? z7>PaGm|>*trJsQ_F9Ty@K?d{0#%u3-?V5sWDat(Y)XD$*2gD2xAZF}643+0z)3cx* ziPlc&1`wTV0LLyS&1Q~+AXW~E88}|)#K4O(WxS4o1JqmTz#x5|At!J<{r8C01PAbP z3R4fOPu8#*Bnm)n9uQBUav8A7GsCg&0_0MVOw_?f883_IcPEF?wJG!DfTdiq1zWw| zP`xhRfz`Jwfr2DcVT;G1U~xKuB9~$euh%r2slpih-Drbw;*B zs_E=XDN=hiP?#ZJ+k%$@oR{$DLM8hFB`e<~o1aE4%sdMIc-Fk^3_LnmV=q9RbfurE z>-mE%9vFDwB=bLWkMP%w&pi6+=+fG}FDfn^5af78=MI$z<4uxODej&5UL-|S38aVyOr>g{7=PM_MYgCKY7or&b&krvaencn9G92gYwPsNy^nLx)T3vm%4-qY-m z)cyxkHwrpuqvFbVIj+wJ)EAo`34|;bN|9Rw`i`zf_NWO!5j#mA+l(wn-52FCwpng? zq>}qM&nyyEcqD%>RBX!%(GV9x@>T|nJq|KZTJzwr{KjF)1Pu%g0(@Z!6-m-A1qdzr zQ`M;Svn6bFNgwW%W`It@nKhbt-aMvOy)fnxL@Rrla#X2$e&K-b6+H#1-GUe_q?_QD z`R>6I$>NbcXd6|1;a{in(xy=pBCor0@_K*jf~m)R&VkrYM;1(~9Xy-iXr$rPjwfmv zJ=Kiu(IG>2@#Mj6^iNSnM=;vPHM%A{v;FCu=}cZ%W{dUs(b6zFs}Gw?h=Xy-2xnEq zF8^5Ue7WW!4hn>BaS5p${v=^@8vQ(A4o4P z?=4!^T>oBQ>8{*uZ<6rJ6sFs8yRYUNwqmfOLwRIpLZ9foFXqZ8T=6)6IwWJfY!E`C zE4^)szaQt|wUs345Pr)m6daZ91+r)%Be}4q~|9 zz&6%_;`FOUD>vL zs!jxc1l^ZnUOKf7Iqu$McRWwuez;dYy&I~G%*;zo;5e5`tY7YUMpzusydEJ z{j9yt&7h~cK31Qzj*xZ^dc1z7WjSwNkG1JKUo+CF23{nln!v$t>S1tNTi>K!QgB{) zw%J{iJRYJcgi0J*FDK%AF8O{UmV4u>3{~;Exeus!K5Q=f3aSl{mSMPXyL!wsE+9Rg zNX}gOEcm{po;>sXM!xO6uA66p_l`;;6zQ&fJbv)VzEjVvbX)eFeIAwcw@^$M&TWgQ z{*v{uuXt~KvR-8LaDIn=e9&%;#@z+z`gD5jMcZn*Uj%I%EsaU~gyxjKUUd~YO#C48 z;?{67**zT*eR=X}+Ie41>%ORa)@WNzWMFvRm*8^6F3d3xeGSgAFR)Hwqn@oH zC*>rucwnS)eGDZ_`&MRG4<{h=G}}c5{{`>}F(GG%7rhO?J3qlhOy4*CTRg&`t;|;>?9lYv)qI+Zif+`1P_k4zD z_7h&+KY_j(zR|oOdm?rFYxY-e>25DxIXLs~B7tV@VnZ z)6L^Rr{nRz>B*NJN;>h}k(1K%<*uJ@-J8zu;cdB7NTwu=R-4|cs1QM#A5_SoZ-$v> z(R-Kby<{qxMx(a2{%-@fMyS=d~tCn}OzIP|u@tv#6_@HIWjp z(Qr;fj*)WIfyRyf2=%fgqfbH+%R+gJvW+H>qRUp9MmemS6R2wFX_`S>LS1vUPMwCn zb%!m7ro%=E0xFcB$uRb(&uBg8P$mJUTP(a=%vF*`-x^t7aM4B zlnI*(mQ9a=tnbKBA>&3Zn&VL`nZ)d*`%p%W3J}e!hLX0p0FDb^D5C2bj_N7MH%O() z4T+*)<7t{0&8Z^|*w?877OddtSIB6Ud)mu#HD&PUag+&{24kFGu{j@*Ixt!G4u@y%crRp$bx93|55! z6MqKHLk+xAa9}D%iCUCW`Qad0VXET@!be3$%p{6>1M z6-YFal^G!UC-~2*asD>+N3Xqu{v?=JS3I5CT$q1ChFv+$>k*{8o%s_A-C}vcQM}z3 zphifmwQJ#7Trf8M6iDVQ0zXHR0)(7m2T(hs5!z$ zqg8V`OKWb0gt(%>Q!3OZqr+^IgOXx;p4v7qdi9C5s>CD_%U1eru!kR8WOPKPWoftn zZZ}?>^2SXgsD6Y*5C{zg%;{09h*D^=V4buPkw64=rmZHq^HSQ4%VOPTtKv8UAmF&U z>2bukZjnkwNQ65ZA6#3s!twD|Fp^(!Q+VV~Cju3p3}oaA{0Vtb^)1R8eS|axIjKWUPOiP8+>WBtFf= zl377J9B9>gBuKzhIz{`qONQ-*Iq=_02lL4&Ifa!IX(T|1wX{;!sH8)MHIXqPXr=V? zfA^yV9oCqoT3Mx64ePrmEA;`b&c^`_k|d0)vEf&sASzArIaO@ZVZs@w%57)a^AeyY z?*&zQ0XvszKjIVXrS&_aj`u=PX(8Fmmx7_?Og`(iN9C4D)SB&9-nHo}N*FsKIx1+T zp?Mx{qo)~Chyt7FSWEaG4htIsjsXywMz?s#9nT*W@7?-qS zQYo9g+g)xiI-OS?`u6+%+w4N6OblE!lWLmM?1u1q$^5E>snGz89T9%CF#dV7^*_A| zFmFCOs?O=X56V)L4H6@P{DzNPP%rR%ffg)}5o40$pd6EPCF1k)2AA1jQ< z9^<8P*vjYiD$3IxR+$F!5=>Z;nFchty7R?Z-aZZ~)0B;E*~`z1H_w&^D1X4?vYI$mgGI^q#8%%n-D)X)*rG&VnIu{FwIE7IH&;?9^OBdrD} zE34DSf!02F)3KGF;FGh@YezWyEew1gfqq3oP6KVI z(#!vpH@NOlmfx5L)0mf}jVb=Ph(3ukag~OlP*+|r8mf!T2nwp=$tzwztP(0LD>40(_RAmW z&bN}!HTSA6jwoS?nz*u$p+QKeMM&2HlCB|cN>pZ4kJH9nnu*u3x2giWR=C3{w%tL; z)kIaxm$eBYpYW1=1kC5T#uCh72$Tt?NAR~7BQ||E5>tjN)R4(1729>BjAV7G)9{#&0y?YZy7=Fl7KS0Lc&df{c0cH3u3)C;;kP77^Nc zdSH)4&0)c0WwtUKOGIT*Vu+gW2}MSVdc8H$JpY8Guo#XydEIBMGP{e zVa5S&!nZgziR);3PhVDD^o(-9mRVVp5J7XaF<|P3OcF$g^Z5nUv_NT6+$KR>L24jg zv>`LCaj^j2S@hh3{;bI~fR4#Hqhw2qI5#(j*#4Cao4^sT-LNs~5o-00QPV3&K%QaN zs+A)4U|$HEJrf?f0O99?{x!=BQU*6v5|IL>-Hrxg{HcTXs(D3y>BqPsaE1+vn!@r5y?U`Z?NN1Pev1S4n+lU7$Z zyuPha`GAel4rqUxNK;~L!ueZDsRM;og>U1x<-~4>_H2-!X{nB}q=m#255o`O;5Kf^ z=l95#hA5dKx~}w$ITgT7#6aH`4GTt+Y>tD?Y@DYEjo{vZ=dm(j!fA#1XL3sqf$e~t z$-DtBG6dh;C>0OzTqZ^vjm z<-~BCHNyP>PG9GujzDi4HpykG+$n3&d%upy381Z-OSg!NR_Ux5Pu09--v(B`Kvw;vdfw6>x`{saz?*JH?nS zna?`s2oLVGFqR=k2kPWGgKy1fc~~?0Z=BKnCB%*;Lsy_Y-+22BzS=Yid8U++$saH| z*v%E5c&=gvOdw&?a{`#T-)p7-R z(d--jvS`DOQ13Da=^+lq9y>=w3B)mSiHISZKI=&#CBh*|A;OI0%B0- z#;O(IR`6F+HcR~Tk_vunH}Z|%Q+-}#pSB=3b`85$9kK%P1&wVScWTB3|KL^up4{rK zNgdx}FB`ZwBRjzDzyfE5E$=Ixv|6W(djkm9s5ENVV`C(L!f1TNLa7 z8{Qx9{Br>_(M{^=X$9m4v%99*8UcZC@*DNQSqVEcYe5IkbV_y(z|753SsH{U7xn$3 zucHY!;UB*`aJ4ie>n9>bX6IkNK7i@5WL^}I&*rD5GHoRFaqTw*@ACmdU5%O6qeO~* zmqWHXv=c`=9LovOD~ghP@Ey4Zd=;REv)Kzd1XLGd;3;g{46Rw^pA;i|B>;AUYdWLc z0$%N+PZAJvHBF{jWK?e!TVP~dJJwk(mQ8)&1q9X!od{z5cMxcz+9o~`$bu04GT;FB zcy)r?-}Ob3syr&m2DBI5IlGEQ*V2cxV*PM_xCE>&;%wjZYZM2fzuJkF59h zCmHVP?xT!4wgxtU6!dri*YkI@X#XjO^%Va1I;!;2L0vJSy)`9pjB4*P|K|%Yh9~@V z=korqF-sxOB;L|$|ExeKe0|Io8blqFlvrqpuMhEosagb9>!*02#9$hGlZQipM4cF9yRpLyo`cr5FB!#=skNy)Q3B#RCIG9r+4s3pV=_DuZehFIZh8^u$ozoNA zo0^V=u854TxRo%D^jYcv;iKb@*i-Tfg~+u&P-0LbX|fAu%<_pp|MGU0RkXlG*BBhX zzx+bj|F(2?puDekcoLx}Tx3`7i5{t=kbO)SFh+&wS;p*!@RcGtaFWowO;z+R;+Z|7 z<8Ly<-=Hd)u=)!ap))*CS9^H!{>G#Qtoa4?RvzHO5AgJkqPGeUN1k;zLId^e%ck%> zq=HXUFxMM8(uv@DDjV23J-8lvdm|Qeal9nkBOYB9lG}pWAe|BOnOiZviW9FnezrO! z_K?&a_(}j%R+Y@>M+qP}nwv+qrZ{Kt7*xxyO-;7cDwZ=PZ)_hjYT60!C zg~7~xR@!9hH{qlu^=ruM*$~)A?cq)ft!af>UD{}P}7 zOKe;J{lw2Rigw^@cR*AlwB6%c-qWst*$yhLZ z&(rL0YYv6wo1XK*r@_rOA1PGqJp*gu%?eH)Y3z2hO?Iyd;f1!FoXqom>pQ;sLU=tg zAm#erC#U<|YlyF9DRz#I_lDr&g{<>+km0-K6%=qy`|-|7x0&o1_4EVtN|K}p@{{s_ z`qMJ(V-$sSh~U;$X<2uU_vP3Zv+D#X@0Mjk+FLrIfs$}($P6^%+e2YHoJ&I^HTNmkPlEu$8Q|Jz|LTmt!IsgYg?uR5UDR` zB+cq2)(z7{_-Fh?_?PU2-_O~Jzh86{WS?~t72j=<-iR@DMHZfA)$XTvr_{>x2Xw2& zrgy8<%8LiKs+aj9Y+3GnGcT`3HGTNMc!B=P@v>HhR6|~R%+?1^g@hpm5thsD$ua5Y zBLV6qf*~7IQYvk(UnQzds806tY_L(*Y?!rJv#)r6v)Irmqi$9`>&y@E3nfsI&u-fd zP}pi2DIC9hJ9>j-e{!92nPPuh=bJTk8-PzpE0_wumjP!TsKScl8A1w6Q;TAexe?Cb z5WyD3o+s)6Bn=u0E<;hEh#^ZOo|;LNJQ!2X&$RFUWUeZFe$a^Bl*T^B2q>WBBhDf^ zxg+WTAGZOoLmxjkrU;+K5?t1>ZceIr*oHk9&gu}FMbB^O&oQfTFsfIHKOI|yQ#iMy zN4X{@*P-51+;GqTEq0YidBXPH^A}Y9G9{iDxn@gd1<{FwF_C`6LlfH*MupVGn_M*3 zV}O4_ncK-}+`Mr8qTYbbvuq7^8E5usAGS16$JAvBoO`KYR%ufmGl_OZ246pxRhCyZ zZTtj>>@0J;lXBVoHN8ed8moegU(CHRvL{}K98rgFO5CN)tn>B(uGkbR8~SS{`Ux+A zbQh)gYiXIth~g!YH=oS3PJ3Hgu@R9s!YuxjqJ>Uy0O|?v%xbcA&N`6#A3~wm7^#x0 z(PRZ15T!bQS8&r1^B)`E8Meq~MY~%$)w&k5t@9e+YM02t<7^y=?)|h~QpB*6D%MU(pTk1U19#8Zw7O-lXv%^?vrx>XJfI@^rlMg~@)im7C~o2T6Bcc4j9+_~sbbl` z=v?_zrhs7O1&iBBPSAl}<##S$Cr{+m z8JLOPEz9+qA7T4s2l)<9UuWIu)!W1( zQO08OT3uzml!N7jL`9%-7nUD~Cout54%X_7k#XXjBNSQiM z{qvQ5uJiKqPF`t90?doJBKHGH9Je}oCY7Ms(ymAlq{K036ZM1?qCq!w6B2IUs4BQ> zQ@n!hTCbnoim^17+=Sc0?nh)jB zducgdsMAR?ZF{MSc#Ti`W2P}!C)2=9)XL(`g}|*!SMr6rf=S^5+Zm8d2&{6kEwD#z zJ#Bux%7V&xu`M9apWhT(DZ->ubwFthd)9sTB{qSscXFc%qHAorDUdG&cX=y^#C$Q z8BAe`Q|Kxm4s`Y!?${gkq!^**XUQ4yEH!~6B-5LV*{RSgX3m121D&Kwe5()92TlwY zpI0K7+e``DFB%!x+7IDZ(DV7;=&S`Zz47Kg<4{1cWM|}eS=yb)0Ba(VLzxzHzCPK4 zF5sxKoE`kUr$Ds(x`rII%LK$qCiwh;Kh6x*I|Y*jvvYinaM7II;v+IYoPmfopoUTT zB2Bz=tV!>e(&xji&LL38>IB&SOx?7rAPn5{a@-lYS*IA{Q#q^)D>5%aT(GV<4!DviyZw z(hzdV0!6ZwE^)l;JF&ld8GHm>(1^uK+Di+GDv$1PzrG5rqHYte7BZ9eCSVTb~s<^PBcTPURYMN0;;Am4eIikTWP%Oe7QG;|bQph{9!x|)A^tFDb~1kG_h;jAFW&Br_U8Zx?%2kX0S={o@LQr zq#UoOqT(6YBtEPL?)8_{Bfs;7I$`$2Y<>rAQP$MSBHj6fUE(9X`xUtO?s^fuHwW>O z?#N1>XC%$ZHVJd}=x0@-^f;u_o|EemB-};`R9BV@0K*Nwq=P zsu}PJ5A<=$&}bbO5{}CbK`VQ_d&sauB#)n1=blDvn?G@$s`#AS!f)iP@^P!`szx5! z7ov3sZ$H^8UEYxf-*&y4_8Ksj_MTU7up;wuIK;0lBJ;h5f4C)X;D5Apmx##-lLOifM zsg5n~%N1$*jG5@Z^!j6UA}@6%YlBoYJgO_2ova7fly!oV*#i|jX_0Tx69ISWF(ZM@;M=-FtlkayM=LK5<`9o5? zitO~Pj~x{{CR;&&+SaBpUMI5?53x7W3Ob#x1&Py9>m$DCEFFqFV)quAWV@D%9<+<( zao;IE^{3eDOe)@Z^Ly?)D8d0b;kQLbmys(8}Y2j&ZPKd&fwyGk#F)nAB<;qlFM znx|eEGT|=r;5e$sCDz4mb=+(Ad1~J4Z|mlxX5JRh(jqPEH;#C*aGE=Jd*M%X*c*;! zhcYR&melShk~)%Z9+u*#OgL%(SozF9C`3$gwCX>YJo250e0gKfA#DVZPO_CU*{-!+ zFI{;5p6SsJ*BCLeF*on8YkvOisdUNB;7QxyxE^x@O*;Q(Y*9qzlQy0D`M8aksq%Q3I6!>FtbHnrE{7w60{WKfQ)3?%`yRLkTdd%7sl(TZH zVSFks1Y`Zn*>u@vz*Uf}Yg1C@i^pDYD|Kkf_4bpH(`i&!GYdYMnyJu}`%`cA;v;?} zdj&W^a+R6%{58rNx{Ld)+0ADvhjVm%ba!y+Hz_XG6A?{* zBY>dOW+SmWW5lu#Tj#=F3!{`gLT!}x@j<=bv#0Su_ct|ugR^nV&~SyiCrc643hpyg ztor&r=}sw^YoL2!?c|r}6>M3iinIaNsAGJ4`zcs$Vr_|SnWn~0k#U#X82AzgDssV!*Szlf61r}2|QZkl~ihR10>2C%QIzEI^P93u=;HG<#2-ZF7ILy9V=C%rs`Er+hS-p4oS_xl1|r-5&Y+lH;`! z&AB+F)#N*$Cz#&k$M=qrCN|B-GUI_yqS3maylkY5l&RpXE-gN7<{qL(OLxjfzw38y zmhJXy>6@D-O0L)Cb^eamCe7HAA=xj^+d?{)7U<}3jZGUhP+lug@LWbE= zrL*-q1B7hovrT*)UxkdiuhC+rolcXIrfp7HlBUg0HrYK~ulRdG9}mPc*d8c%$GB_( z?)Qy2y<8qua0c4CK^7DVozd3lm7f44DNN|4{X+bMnhOkW0vj&5los z7ce%4MY?5>>st02iHYRu${CK!HWmIBr33|i2OVEA(9%NwOEK0@(Z^mst&lD~rckzi zpD?K22-!hW$3n(l!vm`a<*2aGRPA^meA=QWI=tV`Q$UvX@aS;(z>?*us^sk6`%roJiQ^ZKyR&pfxyV>wz zpRCq`k=XJ5kp_bdSM(=RV0Vb|BS!QqQap;?C=9}piR30l42mfy<1i+qj3KFGRQgE_ zx(vFEy7ZJOwkcN_vFZcmCW{P(<6WuQDN*BaMUgLoFY)aCI3_Z5KT{=&!b|imQo)L1 zTL#zlZ0MU(+r|YC5$_V*N9yS+a7Nhen2yF<>@wL0&FNK_q z*=zaAOkuJSo9+g%Gop_SIM}b-(S%`7L>+7%4cg<|jc9Qs_ZU0i+oRD$Q0|jDDmI(1 zJ6$5%kg}$y_e~shZg=h^*_E|0uRpDWUH-f@wZT>$Omy^Y{#Zx61aVDk>tC>QUPry8 zSnA(6ytIRFM!Up(inBx}<0mu=;t|m8Q9Y)`0O2L%ql4@TP=`S54YDH?2t~>J#oueE z|AzpAzL!kDo=zu)pa4Q$pz*pUhH@Xeq}NElkxn#)k_rh8S{FJSy6hKouSTxYGygJy z6_O9~Xi#P^&`yq>0vojwl(Rtmb+VnJ8JZ4MRnU?^`t_iI8b(C#u9baFHJYmA&xqMw z6M4;64KC^pstzg*Nnc6Zh^_%W$Z8O%8-a`%0vJTM9?jz)PKatf@^VlVG$HPTT&66D zr(eakpMT>-BmK1!hK2a;TPT1`8S8)JQ+9JOHuE{4~n0}m`mXtXh z$-HT=qhcvWk#q1asu+^)H=mO@L(+t+T!_Bu#KtqHrPsTWp z#w)9%X7{1In#v08fp?4{W!`antr5#(@d+_0jMtoW?b3-n6O^*s{Jau$B#)B z02Lgx6b^eKMu*h(7)?Hq|yuqMIJgdJjI0aiZ4>Ga5Zt+C_jtwSyGBLj>n zSM@x95^II|C5w?yB6Eww-S_@*Cd!_HM4!hnj&4c}NG+0hFvJ@M2T|*3xXzHBiz#&hiuU21|__Sd*&G!y?Brykr!o&_Y|krAxNP&P-U4(z{cq zSI8PWQ>#*tVB|Qk)uqt7Ef?k#TMpjW6xg_lI(Niij1rTN^2t_9C|QoQ%R8Am1iC*} zXHhE|-!ccf8%j~Cz#rC~SVh?wHLN3a**vszX zL{fMoL%y-Pf;&*1>|Sf)j}HoHHU3b&0P$VYd`QEMRA-QiVB)--rhGOTfiz?67&`I~ zMcFxW;@$Dc*MMM$J)S7}*Lvu=C(JTw+ZO$>8vY8>zR?9H?lGIt@ z;-c{vJ-jUJq5#=23u$XP*<*EYsVP+M$qn4L5?fVi1xd@nX{j7>RkqBL(M;KBzXFzr zQs=&5Y@RiXQSTKL<3)^`c;=EF1)F)4`hqa)ZK@1&Gf^bPxEmLa1!q=|oOp3lmu@H* zD)X0eHS3)uD+)U?b4y!!4YVdN5%e_<3M#aBAZRyh^Do~9iLu!v-tJ~gqIqd-x_PIx zWNPD2nHSCJTg*3oiM3^hhScrk7u%tZj$hS82lezD+yNUO=4A{}@O1{b-TEOLti=bb zA6%%$Dv|>wL5arZnbesK7AamCk5l#=p=0&|0d*Stqr7N?)EKpr_5G#6KWZf_6@?Sw z%Ou?-A49c-j#SUuaSqr^)RXfpQkqbj$h3-Ykr?H|D^vhoRkqCr!pLHo07$g_Vem;{zk$8~Fb0RE2k2_997csHqWqM%f@MXv6> zOjO4Wg_x+@y^9`I>Z&rne4(&Fwv{7M=@Y?(6g^*7*_X6F)&`Xna7JI|ceb&((VPW_ zwjT2fzR3}yDa^G4xVX8)JeFMDJ%_<#y$rI zb2yEHE@e2Csl4->a|4`dAn2bX#Sj2dUcf>i7LIqV>T$>cQie7Cu zalATW&rsE1H7DkQuy5V=chC3oYc%!aq+dlPSui7|vbDoR<>}UlFO3$_ObnDSjtfMo zdxtMznDnWpMxrL_M)U@*-_FiM>7eCJZX7D8IQ-Y+>5{rP)SI9(JD=iPV%-fG%`I_mC>smb$Gz7N3+Xhned5y7A=EszuClc}E~ zLOy~T(AKG+Wfhoz`>bqgK~d;nWg}t^`XMcK`dyX^Nl2Q(*ku7cr93I3U(f19TeNI-c41 zv67FA02l>L@Btj7Pm@54VFQC?a2VlES-i%tpOHhe0M&d_wTz^3F=~7jVmY^Ym?(mb zuL17QzD8`Uf!M%cjTmR_2r!C8jWCB^H4vC&8Yu6Ta%yT5bS?r1Q`it}r2MzEq!nR3 zAsBXHu^b4Wf}r4Uau_mgJHF;ZYQZ+Nh8t+9HkgACXzGw3A|TcVO2Vo!YF!h}*xNR_ z!YYKh!Utq9_xc2Eahf)C2;T)h46vZ zjF{o#l@;-*0ck^&#Zv^ei$0I+KeT?9+r^qF?^<7$r)!-pS7vLST|5XL5>cWMqNpJw z2t*yVdkaLk#!sJaP}RFD^WWGYu6Ahtf7->bRU4Vfv0Jr??|vG7W6 z4WzL!(->BY6JLrmL2uTI6Xg(fXk(TaUG#x9VQ$unD?P-VRyS?s#6)FwjB*|24wF2 zqu?RVm9^g|^uu9(>K6f&`;#AxS0IGn*~J-HgjL`fb}ZrT>bIZRZiOnTRPpe}4r}kd zHY;$Av|$k1bm6z7P6dBZ^dj#=mV5BG%arwrIi^8DuQtl^lDq-~l=h2e?<>>=yCe4PW~jjT{V=j#6{&c-tJ>qneRl2g@$n z%7W*hum^Q*x^m6bu3SHaTCKSCHnmN<7%)w33zaZyQ+1RrrBUs?a3e4t6FCzY!rP06 z^2x3skjrxjNdunqQwb8w1YSnEW%{p+c2&i`xYg)-8>2h|As*6`fc+xzu(k}|G#>@T zOyJO33`1L;!O9E8R|~W0>(A=y#LOyAs#g60wtw8OSxorv=gBZPr9bVRsYOZOeUd0ZePXvf(i^Wx(LE|RzH^WE0vZ$$oqVS%4W(3FrYh;iw6kM)E0kF; z3V%=ea2P7WG!zE?T!czzF`cwR`H7a^q`DkJQC(49t**RdY7IL1fO@Mo&^}bNqT?U` zvZ5?Mm5!7CfdNio6^Cjck9yk??FB=8Gz^Ww%IIzt@Q?{@*i26peSu~=>BFK=wO4sj z#_b`&-uQTifft!q=d!Low2-0k#A8!r$Xf!q3XS%!^mmyvZk;vvVkKaYc36o1Lt zbH!IZJSp(qs4;ygO|9RGBWK9!`i{Pbtjq1YC3{yz(TTn}oZwW}D`iZP;_zQf^ z*KH{abFX8IC+2m}G$~tqnW@vFwhbJNUYQ_7n3r+JXLqPpnoxFO$TuQ##ykS1;RlWjf{Q znHR%gXdfn9@VxC#Z{t;3uBH%W`zlF zbv+2~JnCw@SCl=BeCTpLd(8C@7JhwfFU|TMdGtDKUPdVv4&ifi&+NB6uYP}tl`K5M zBg*s@qGiqY^!ivC+KSuEdf2tqs3=plZF4kWJHh;N-?uDoyn6nf1-tb+=Gf)?{7ZB7 zv*?oZ@@sVb{V5qwTDZ%xzxC(M&RlY0cKhq#uZ#8f;$ZyG(RkX-FLG9=CD9A~dhX10 zPu0D>WO(u$h2+Pd--k9jnX8sMx*KVSYx?|X$m zq~AF4h>Yxv_Wyj=7@3jKImAsbXH4O`g9OysI1JawdIcmWYDsb4Wnz#IO|c9`-*^xY zMons<8g|#19*K4l>mHQrJGyN4da#(9YBw47O?JUXXJp2nHJ{Yg&86182H|?T zfVr~Wtzb|`!*X_Ez^6m@SYz{T0J%q?wZ_M3~O?5qw zxA9_Qo?MRQl2)QNcBHR(-h#eO4NLLOX6St(vg#)d4l)6EpS?xaGIKHCjoXpRQqHADFn1T~H>9iJInduW!~caG47| zI>D2?Ha=M49~{dSk-64yPOtJ5u6LGg$uFK;>0&Ai5VKs`Z_ojGC6vK6xiq@arM9JD z&V^WZ15XJ@S==>nRH&TQ$CG_oyCqoKu2~!CuWeUn%|{tvzZsgRmzaXDo%?Rrr;3zX zzkW$ow8r9|NTfx^ucPh%TH{>5pVGz%QLDi=!?rHQb^6iaA8h_pTX1QXrgS#SiE=}v zX&ToFeM8zd@9l&?Ee8uXpWTD=gNvL0D#vv;{vP_C#v|M(R^y(~BkdEFTM)lUx7hSV z@&4+B@xJXI|Cs%i$~&u5OgHc7Wb9t~mG&O?mC_?tC(m}q^#ni|+9BmD&71Qj$eV`` z-jYK(48Fl{YbR1o&-SyKpqcI%o(75rP6rm8k2>~IaecD(#pSZjRb{geOwGj(WO~7*!G45$*V!3@YIzihxepVyq$mImKh;8_g!8zmd!B<#hlE$1#im<%wY@|f zPJxYZV_PQAwk+AQmAH;ez2C126V6^5*XA`VjivR&NlIkF1ItC(Otu;>H3D@H*I5mM z=~^0P=OWg{Je|4RyufM;r8ojqo%@PS8nuMkhXINpn0DAqy#dBQiBX5hZI^@)YTI2w zw>FBJrCf;{q{r4WENU&P1q+P&YCaB271!bN@wRe&8udHB!wg^}rh9gSvfn2YWf0m?2~_6k3~t6zR}{wqZ;33jZ^#)O z(vE5?!qCu|leQ`q8bTDl+_M2&@?&W3aJ4ysqMsdPGL+7g!oPm&k>>Hy-ob0+bMXXz z6&xWqmuBvwv)AZ5v{sBFPV_`Nzq|1a^#r51<%Yu(LEYQeEee4AJv9pT6rO^0Cr_c;PZi<%FGIc3OuOP4%YYc*q}b@S4qL;Bxe}E6-Sh2o=RUeoO2eDg9xHo2N0bV_}Jt@`7h%wsF)u3aQ#;HmRX#4?Ws=)FH$V6r6aa{O(~a# zHUb)A4qb+aAcb6qisc}frOUwWUHrXe0%a1=|N4L(-djrHA`-Qp!sTa(g$Ng(*W+`P z3;UffE6|<}L6$GzdrS^qs5WNdV3?r)GHeRm@^uDR(ALnc960?xqBPz?e{3}&2a^$& zg|w3yX!*qm#uA(TeGIoAa1Cqz#(sai|1vn?T8`1kAbjSQkxZ{rOhO^APU55KmV=4KV5o37^!C?+CY0E>R)R0(xWNy?t8t>$p-Yv_4v6#ts%8*#~?wIBgGn zKJ9J)dcInPzvWdbQLKfGA|yXmI{8U8@)i|Fa{rx(aNjKcWL} zP>-jmCz&TR5t2S+=%*&c;H*6~;jy+*dT`0W-@o!0@uMjcB#m|jW=Fypg?i=Js7q{b z)*9g717AecCn*>%LCyR@;Q@SYauN-o^x%fv@HUd3l{q~#BQ=AA(UAFk6U9#3#_lF@_O zP&t}qqYnhUg+h+8lf^DWLSMStR)KqS9qDo=>(0#RYmnq!66a3Kudvrl9yrw-w6rNt z9?L<749H+EkGpET$2y9kLR53*SFu;M+Jbf`!B*mp_|C-6cs#M+1-gY>1;w+HCk^+u z3Q`gyYPCPef3C&jj#L`i)^f7P;0WEuawER}cLDXcZz=Lzq5!x4-+usC|IN<9+=ceP z7}NgeBLL#Ge?IbG4MrUQ`(cQ`ey{77g@q8HKX($K#}wxOeAqzW(cI9++=RxkLs{E4 zoestONL7ozL;^u`wL`@H4+oL(*lgHLr&6M^zj*}~Cj%++*z;9g4~UptowI^FU9C6o zB=?iu3!nRVc#xkYiC{)ic9!z#s`lQ-9zG53+cVm~t-Nv%M$! zCP=m4#D)jAD^8&_Qk+1g5hA7Om6G?H={T}T{fZUXR-s&P%29~X4wkiwBns$GQz!aQ z-k-2Bepg%sUPs>#psKyXy}>7WYqndkf|okmLWWM>wJyu0pz$avp1=5?p-BWMlR2o5 zZ3yCdecgh7kt8M z3PlzuZyO1Def9c2?cbv#p6ru+DY^Ep!_%GJgDO%Nz;wmH$xDYnSZi4li(~Y-1M-%L z!YD|tekl$l#ZF0AU!qXPGMiSq*%x<$<^?KEt{irxJ6Ti8T5t&H1~#U+29SD}Q%jO9 zmfsk71}w9=k?N;gANHV2*AV%+LyC{six^TTAz2LQ2_p@Qks6hl#>RMvzLczXr#H;# zDDIX>wU-PsuwH7*2P^j=BC}x*UG=EU;!0Hae#VIJ1(L}MYi`_k?^e{$F zOJit>0=-{m3oq#guDuat{06ZgZRQeFw}QMHW}Ry`Pf0zreXH!oH7|P`R70;4+m9l& zL`ny~XcALQ!4OIFUA{+HJbl?q%!)VR{oINl)zQ2g(>S!|R7qE!NB+Gf?SxNLu0ple zq5S>r`+wo|pU^`-@qkDNBr0Eh|0fr~Ur_#kIQ?(v89P{2C`!uq(ZO_HsS3r%D3BZ4 z;RZm4;l&IJa>+mlo9{6QCPgwGs$HdGK;;5E5E|!N7ud-&d*dxLfOFA{)izusm6Q4|wH31@o>>gF+ zzq(!H^u^7gQ6~1Mq%y-#lRKSdj%@lUQT{-H&@ec-3&d(IJy_jc!_;t)l92yS9u+jR z{?;s1MT#1Os95nOnWIR(b74NN}^ukp4rlTKakGy-&T@nuJn~_5;(BR3gn6>h zfaE%MwdX;#XXE?c=Rr^2Yk{c=wsTvrt90kt|`g~Wv&9ijf4P%;6J#N|61lU z8cC{ADXCF$>P7j`%E<{?@(J+;dAZSwAi6{gL(7NeQb`3zXa^)oJ_hlyfz%QARCA9K zVRi{V!2Nfv53`b?HMJT_a%JQk?g+ud-}D(SWs5@x_{jhOd*nYZ8UKbcLnlXP zb0=dO0K_)btZmm=5I!$;?I94lf%e|5H@=nD4}Zsl;B6-I>m0ai|s<@@;ze{A%4XS z;w=i`&qPO21#Ch)70RR4Y7AP|ZZoMl#pqFtj`Qm~`45WM>xV4%%{U{&fU#)8H1sJp zTNM3{CamBFGUqR|f?|g{aLYy%FsI+iy&0?yFxeAg1KI?~_MbI^#9E~X&n?O^*Zppl zs<*J&Qz6uedVZD~&(1*{4q<{er18UOM0QBoxh`L73ricVar48~r==wSRF`ankryKz zC!hByEbP6&yDE-S;4HP;tgHp0>IeUh(S33;9qTNXc(|%SpGe;pcZD}I|S&8lPstcViZzvM~BYkhth#u zwDq1C{e=z;hHzmI8>K5sVxzqZKrTxq zClr7Jos($8o*y*gPzu)!5DTf8abb>U;>3x#oB8UZL&N+*6^cM6zMuQ~RxmO$x~2uP##=ISNqkislRZp;hT zMfe8e%k1>k?_5HB9y)u`IiTzq5kxvEl6oRv^C{2aK)Yy;Sl%ue23G2$!4QnvC|Ix~ z)33{c_`dC(4cY4QWCptsBsrxh3@pZFdrNg8vp&m%*n@V#c+H=iQ!t7e&jdceyMuqI zOM0WI;z^YZQ+>9JXJmgya=p?TXxY%u*q+1J9q%7t$^EEOL|_$|OqfbGe`^&Fma;N_ z)Kevyjxzp|DpT6T^GxBUL4?4Ueb06H8F38!YoXL)Gb|#0Ioz|HSLorjl%_y~HMdT_ zetxqfJNYsnj5Z)_5~;+-+ne^-@SHg@SCRwf2;oY)6mlR_a4rabeZHnaIKO;u!(p#uwLcWOj$2@IMUkhQOr~RMwiQSp}q{q-m_@GW%3agxE-Cbe*8H`FjX9d zPr>enpqRQy4ewJRAqmV=B11~VQ?MUC3Gm)cmI~M4X1+7=eKarnifhx-GG?7#chUo- zBCYqTG>TwY%W!xc5D=`5hYHPRS~~q~>ooNqh&Iwz?4{VKr`?>T*&||PgYnAL3o3p$ z5YRitK)q`UePh$lRI6^Vhs_sF@vjm$E^cdl0-T_NtjN5;(2i`i5$F0{Ev)BB87%8E zt!yjwl-3=f8oqTNa3}BCp1D6`9~;k~6uPU9c(abaq|-RuV8>ngg4X=l+Mc+Astl(q z9FL&4`z7}lbzdsZz9PRYx4#p$X8rKMxu|IzTuXuoqI}hH-uqh6o_%gEhS_fxb%tRm zE;vw9Nm%JPt$zAjwCF8+S|JB;qq+dW|M%|nfA{V*;?y)F6S6b^aPJ_qh3q8~4K)oO zT6|&a0U7;qN;y&v;`Zhy;-xwk^3g~!(6f2Euyg8~*!Vc7n7dF(pcWv1^X=&O` z6e^YY(u>0V{&lceZ8Yy!j_}vvdj3%HRlB79zC__ayEcH(V)+YSR{;1&JJCMp}LLnys9~2Q0m&g|&Jo37LklD~+2dTxe#}B0t z;Xvoq`@`;(ie?}enG|Rq@^9t@T%d$y093LBgk%K&K{effm=myJ&Q1JtxBgT4msTYe zQQ)&_9$H$h;w6}2#;Grb!dQH<8RPr?apUh?F_ERE0mK4AgzWS`f0EO)x1~t3Hsld> z{ShK=Z6>MtBeW$Zn%hj$#kWO=RyvmC;J4;LkvawH(k9|X7YbEECAJ{%SB)Dn8^Mg~ zbkU6B_YF~Fpb%6=kNSo^)qMqvAUl8ymL-P-wUUrm^EdS0W>yuQO^gnh)fnJA=ReNO z(fO~LRVc_y_R%5uOjR`}^Fx)K;dvn{^+Qrhq0AS{OC$k$21`q%!4>Xzc{*>L_HCZ? zH^;Qmu0MIBt2UZ76lf2fX`mABOKXa%2K8&U?139=irxsf23nM#LDyk&wHJ{j={7iL z*=>J8P7<+G@SeeXZeEq3C7RsNDH^qh+D2;|eP`fLFHMPwl9!LDm(i|087LF zHR)Cr#4thN;;9$15?C3V9BFuGB%*=iT5qjU(Md|er)#{G3w3(u@?kEd>y!7=)g`oQ zxG}I@Rv%cwPC1#!QRek`G^al0q8l8N8*=PRr#7EBgEDzBZKBRvdzjw7IVS# zOaw0ctb$+*L6GFJW1{1nY(Y$7Xo}QtxDUlqqZAP9){O-%J2$SeC)^P zMw3(9nS|nx??R^!7Up9Vk3&XO%bpZZB#k_qSkk^bwpKO7=Dx}bGp9OTK>xZ*kGx7m zVu01r1PGw_=-=btfBMLOuF}8pIMk98lq3Jw=hXdcOs?RM^q0?3Q=n}i6NMyEN+<`o zY)wsQG_X_PzrBNNL_gai0dScDzy;^uDPrPi{TEmiwJm!AM-5M^`^E^l3*OK5A+SAA zy(}RNxC&Gd!^&3MsVWZ~2uU`Xhefi3E6 zW402(cDY~8>m5a)Gbq!`386r-S_O)#fb}~4X>vA78l8WoU#S;EzNxF9)k+pi?{?x? zN>rV(qjQQKIGT@pJGeVEwg?t6zRjN{V?i}}B{=5`dsV*WsKBv*hDau*9_~_^8ao<1jReVxsoSWM8{~6;|_-sqrf8pelk`wz!5as7NF{Im%Cnf>EKngpJM^E6Pz+ zC2$nqt6ahl`pH}hTfQfQ);{UgO{S!)Z|A5krG5|^-r{Det zrDz@~qF}(_@Blaw{5vJA%nkl~-IEDgJdyWK3ST2~J)`XAR_cQos>X4|)VemE zh0B=G5N_GlM#Pr5h7IZwnigTdxHp2)fDw4k>yTAixkA~Yx#&Mb@1Xge!mq^}b=Yy4&Zen8f`-u*Mrns=N9q6fsD*fT!pe=>9iD z=D0L+`T%sV1jxUA9sV(gf7xg!N2ErjN-7rS_jVPOmHqB25Trl}v=h{nN_5I&(o_|c zO5|d)Q&oYLs?s&&V|11B5HmF~vsKcP%WV;$8NiI94gG$iqbsQiD)KKyO9DaM)-mTi zx*aAKpdI`;L~*qD2SJ1)n5}dthk7xG>eLfGwFml}?P*ehoBpx*Q2_b30QiUA|2qKw zn!x`jexa?&;j3yUQ->r``wIl>n$XGJC5#PZ;EL#C2!Fo+O`~M|TqbsaHvIp|lGe6H z|7uAv1_nh7OXi2>W+z2TsM`n$raVW=y*Y`yxCdAR{$9DP;G%#^++<*ceLywD-;MCe zvi7I~7%uKV8Q~v8{u?7q$o`i@{kK8f-`|4%LgG%6hUNl{BKUrOGoiTe7T|xg1Euzn zI43|MA%GA81pdJvsnrrg1cMFt>BERK&}%+ba%N zyz|lyhA-3LYv0-@#$7STE;N9CJ50ge(*4(L!0k3nOe=N3?9(A!4?-?zvgU%D>*PIW zbp_aopZxJw(kn`Z%X5M<3|RGY46in|niWNAz99rzb%ON)p@62a5U5!Pwok@yb)DG- z@*xDQl0oq{LyGenC@VSiXmI{-1kODeoei&CIPWc{p;7IsubjgfvEA5di>nx0hM8=% z6|&F!O#U@DVo-&}Ra>i=K`ik%6Gxj#0SjVwrQL){KMwJvMmo(*R>yGQ1nbnQYRIY~ zE>eK?J1h$vjRthQ)@*wdpo}4_R(l}ruZ38OD#GW2MlpA~pmLL3I~s!47o$}7rN2-# zj9%i(1nVTT8sVq~OUTM@bxI{1EJg<1SW>AfD@{v;J;wDV48_@qRgY&DB@Bn^Tu>fh zpE_VsLLAHnI_k47$SO*Z>C>nW$5@y4e(;;#i0kmZ+ud++dj{nbn>B*M6c>*(uxJ9v zpW=-(Gbw`|5VW|5QH5#cxJIVg3FQ;Whh!FDQ%holMe1C$O2wQYeJn8=XyF3$2B#xDW#>m zOS(IxK{}+nySp2tyIVp~q~YBj&v`iB2mQTsuH$w8vp=jov-X;qJ!^e8V!Q6!bz{R0 z=Xb2il)~i+CQ)NLH_Wq{3)ZA?q6Cd9Hc4-UJI?CAv!cvwSYMo;FFz20GDJW)9chiQ z4{aZM|7qXPB)ANHY-WAo?ASK4kap>*E5Q|%Fg0#HBkSb_lf>9sl)aNvl;Atqgzu=q z0=LlwIoD+*^XB!Q*Ji_n0wVU}DYOrcE~mU|4yicblM8NaAi64Z2B`nKHXBOOh>-){ zeHQ{pFLZx=Yz)n;tTjzc)c^U^jqcB9C{xbVe2f<5W>NheVoD~dA@ppv2}OJgpNK(1 zA6RN$!2J4bY;Bb;J4H_9(hw`n{%jGPzw>*UOSL4YgQJrf(dLRQ?v1k0WAG6@U*jo< zqg5!aToVtzGh}L;9XkS7%yzzwSTL;C^{WOoEo!SsYVH>$?kD)tT#p1Ml3%4nk z9>R1yQlfJh&Ls6!c)tv+ieB0PSqNk{&+4eMOZUKxTK3pmTI%*ACXaeO#GvIu>C?nX zR0JJ#b25U2wG70g6v%HDQ7B>1R+?W|6zx{ow<9CKThry3kSBM&lCwwop_kEQ@qstFB-GVFB>1RrPkSU}6_( z8pFz|eXaoOt#Z}2vgNnoRXgp>!rCH~x(23fk4^B{+N}e)YXV#19$`l)>vE*k`S_2L z%19`$n8i`#&q#lGsYfKri&9VZ-loEsO^uGB8a2pk+HsoKRH;%gv>wT?R4_(P6_I(L zU2l#S2j`m|KHP|^hOhOyv1D$25uswH;KfkwbC+72V9}4q*m;C%2uTr=SO@QYWJxpm zrQV!2M8BKxOo!QP-P zesKAbk6Sjf0nD|wZB|y_cbeGA${qDVxQB95Y1F-L+7!#jj;0+7k+mytBGB-LF9WdvBG^=X##Fo)*WJse14BMMo^`Ln2{FSj`}f z1Oq8y7;?{q)UK)t|98H!j5y5Cx>^m_9`hNI? z_wO&?OYCI|>rSe;4iDhozz?tX(}WScdK6SBjj~M=j=@(RDv8YeCSG?GVeoMRuV?+h zkYdsTf}bY&UNJ$pr#`)NZgy6;?4AyUl;kIfTxZ<(i^+gs7YL6UZT#Imp*~ym1LRWh`xEbN{~_IZvTqp7ea_c zGAryyip8RtP0>b+`bXLcd@j1=p2_I*z8>+nVlYvuvr|D{-42IZF%2V1J6y^)kel1( z$#Mvf5gP3|JYQVBkSQ9gNuztPID(Ny*d~C0Zrxv2n+VN8C-q_;HGN7Sd>ku$>EX`z zD|fRg^^`z#4x(x&H%EVN;nL4*Pi7p6b?V+wnte{)BzZDI9KwyzTISD=kCso#KuK09 zl+=qq`6ftPj3>@T4@~!RPm-hGih1*G6Z}CY8gmjNRd|8k+W;VK=7BUJGjZR_W{xSD zfFg&g0Q6HPO}vDa#)>-cbVQ`K7ShRN86v~If=1@!wEeWtCTxj##v2o!c~8r}(Gu#A zU>O==gL07U-cF^DI0{)ceI!sn9Hezijr761mNd*3^4PgVO5IUJw3sZdG>@fC#AG_x zm6#zBCT)eHQ+?=NWe^xs4!sLmM8E(6mv&|o1a_LGyI43B^;$Hm#bWfM2|P^a&Z0nX z&ysq38#<0Kw9g}J@>G1o#!`>=+>3SD-qRIy7FO<&XBkj@m-W;e$}QfA%^rCSEntzp zPRDe1(M}Oyn&IQ$FM^uSIc^OckL7=!k-RY1+@rx6>SsB9jNtEgOJ_G_biK4@8k%mW z9{bSz6f^E1^W1>R^5C#z%_e&utXIU85h0@I7;p?Ys&fS4E zJ9?yLG6ML5A{L}@GuFP2U$V>bF25_ICstzlHtQFK)A4j|V?GWP38=SMSwL2Hbd#(Y z_eO4;$C$+t2Zx>#3X_KOQri7Q5VRy!K&gqd8|rq1|E_S6&T~SGWxoAL23=-Q1~n{^ zmGB9^J^j|$g2$8nnZb$A`R^BA+ihXs2A4jUYb!ZbcsUR$m|CGrJdD20fg@oxNqnL< z@_Oh5vP}lfcR*3pGo;u*03P4XfJ81SpZ#$qJSTTMsXC7yAL%EWT^%7rga=1NX-BC@ zx2q2fGwc<`x<!zt>F{LC>3#F8y7KX&Z0Fz3iG?T3O-K)f3w}Av3->G-ujE@ ze$Ewo`8pqOf~=x9V!VkLtErx;W?HL8{LEWcF0pYfciZ64yKZkb&zJo$OqB?CAIHYg zWzu?KY|ZtU#eE43ufWVy{U$fCr>zm>4;s4T69}bAn&()@sxMy zd+od9`iA#@F5i`6*A3*7&>PrHBx+Ni?K3v-v|l_Ae}+WbZb2fF(ZMM^ufY7HWNFMn{BFg7vM$icb@rB>=4$9rOup>d80fjO=fz?=Tc8zff(|l$>2Zmot)${gWg)uIOGA`PXqOe1FClE5ls4i??=6@!Xq617BaZ zEOuK#mNrN1wW(`^eZXlBp)Ur$z`iGgL?%Dz!x$Cr)eNot9kYw8U@aMquVm1Kf}a&8 zn0d-neeP*{%`iu9Ke}5QZ^e7PCeF-4S7iLI5B*HNWX&JB32adtf?1F=Fb+Ir{S-7tj;9-{ z8?7cx&Vz#S)V;QEPM>2-nPv=TOQ3WSW5l`VK=0W{%tINwY-USn!3~Vlg`rEW;6RzC z)|1g1C)}Q!9X2z#K2$GPrfCX6qz`L+M9%%gjHn6T{j+08)BFB5apXIjubzu0%VL*> zC_FhyfO6k=DYjpW#dU1nZrzqpsYJGDdOv>~yNB8d;<81NB|<@jsyQ(wBB!2rBVgzC zASqKaDA?qX813vdgaC0-)l+FPwm*)6LBC<9Wv%^%Z2a2elyLE=MHEwJ_d_WQizOlL z@!2loFBG0f#+f|~)Irtzmpb(6?-s`&X~-LNK3+EHfOkmd>EC5zhx3P5)E8Lr^Pg&( z(SA*gQeF5w#Pife+)aJ0m)i=$UND{1ky)|Z-@rhF`P*<#gsGd%ESsK+yogTU)J^ed zU`g#Hb-f`4Tuv~azK2{$;^mG6S1N)7=d8ok;kr)NnS?F3q+h%5>Nf&n2p;9@R9-_^ ze7Z1vGPw6SjU6ebe&@rrujlFy)ji*2GzDI2JVjK$+B*s3GV!yfjy1VS*-?>6Kc5?QkIs+1K6bnfWLMF1il`I1KAv^C zSWPV;$`b4}kAVG*)glrhguSVbMKiXOsRFfT|SOPakWYH`Pq@O38N4p7qI5L1`KrWRnxk%*o|g ziQ~7NMVy030@!oeeNzHb7Tsw7@Mia~)wZRLnVGI-!&_6kF}6oQ&JMvSPm0)w=*DCX zNF>t~*0}}~T2aSLI2ht_ICj*I zN+=YDzzy-MM8%6|l@Ge}rN7O+IsLA~*{0dFX*3n3Y{U zL0>=jp0vtt;ut&*{&__3tcj_DXOROU&2tFu`k;mwI_3Tt?~5jRwxc2uO1ODL-DwW| za?^9LBcHOifW@+)bHqYjH`_(Aw~c12-JbF1`kPPo$2lOx5*ZVTgvXq~(@|IG!adzj zs)D|Jk)Nl1-tr7JT&?3Jox#K81JOut?^h5iiG+~_21r}SWA+?1iS^kr?K>u}%nf@? z$xd8`uH25ZoX*dNlfnllN%nUFpX(ySJ$(4E9y!EnwzV>MoKpL|>G0vV-O~V+ z^^c=SdfD*>)VR4(gmrP$iL@n(ISmBV-BAdNc4Qd;X%jnR>X|~oY1-k zQ^{3+wQBN$Z95@cPbj{CpI2kv3;t5mrWgBR;pq_kPmmX1g>~hMJma9Na7HgT800T} z+&ZwsXt~S&K1llnwT)(_$)rzV&y4WU$>j>#A83n~+m*Mj#nQ2)w7@*N%%JgtOhCCvF)O+$O z&?wpKvFImh^W;YI;|`q#UWr+b%S2(f>KcJ~lG;OvUW9pLRlo1Kbp`glqEC4a(g{8t z!$A<`E@yb=DdQDGu`p^aJ;KYy0n3T7qSMIBU2W%GO2lu8vNB6-mFNq%nYUTK^NV6Oi zxUnW6Q`0yihIVCmN^M5&k=GBrMYDFs8uMYO0i+g}7Ug{ zwR)I-vmtC(6rhS!nsy#J>Fd1I+eR`+8AsMlpV=+>f>}%%(Fro0mdt|eNs?XozW8GaQ?IukE_CbHcgP7Ibms5YD(U5JSq3r& zjL_BumKyAYKqVqx%fdC5dHPkjpNqp@)No@B5O6pm+TxZX8D4K0D>w1?p&KfBl+()J zB0h*rB2!cIGKe20&~6gIk)tAB%iA%gK!Um=m{7;YYIS?9#coJZ@TJZXQLr$NLQCEi zd0woNKup7#^=a)^$OUJzOWea{r5yPz`g7jx@4gjH{LN?(J-FNz=)O3ju0l5my}Z?! zXs|)CSA8W3 zT4hN3rvZA|yb;mf0zqmgOO`6u28VPT3S+&cu{yERmtxf;H%RtdOx6XH)$}LK14uDU zP#Z;SE$a|n-^5l6W9__Ft(LS%>aR92Ix(R?JA21(db*9;eZ(fy`6x1hAwz_y=3@+} z`B7b&rAQN!vGhXEq!sLpKr&o>l2P>)lrM|k)+6?19G997$$2f$9{2a^I>!wh#qHrUHuA~!t%<_Ca_b8U#r5xQe6x1X3I&vz z%7;3TBVn-`qg5KGJRf4dqJIy8rDjJ`PL^8DYC9s;V>>Wc2wD&1as<-2Dk&gN?28G@>LU6q$0s|Xk~F?vw_o3)<|ysU@>?bI zMZR9zqQf9Sg3~Z6^UZrMS03OI#pU;kcg8>+9(CB9tf~UT-tT-lbmmIytSRs18H7b# z-!mtrK~&P_1IgoJq|Ynq?Rzrzj{^#^+9E%d1RPwby>2g=&MS3bcK2fGlw^5SxBGci zp~4L$laiWPzJ7z1h!%yhr4`@#1CkT49(6^EySk`SXUd^ZPs$9c69& zQ#);$OI~(2ZqfAE*)-~5kwcyKa33Fi{HkGAU^HcIFH{8i4!Q|y$%0cWs0HVZNXWaz z{xlJRhvQr4zL%IzER)LX^cvWZ-)JQoEn;`iFz^Q_x^A~VCKg(p!RTJ61k!xH-oLrUb3}iF z)x|a$*s@Pm#?rI&a0a_YZo1h+sJbbEn(bMXybT|`4;5ioa-YN)zReVd4^d^qYJW{x zUbk_?jtL9qDOQ-9G*rQ?R5G#&JyGf_9Xu&$&R5L0_>pgLTt(AyBcqk_CZxE*Iy7VE z@lWE1CzLHjvDB5NHm1-GbBfa~D=SOJdJV?$lP3oBzBm==vH4Xp$%N%+PDjbP;LB^o zn{E~wU1UmC=@Jk?^{b?&O3lpP6ya?58!87-^YbIMY$VESPlmtQY7RwOTmw(!qR6!d@v1q_ccm zV?b}E&?yIR(b}DX+nu0|)C!hjB^R8|HNoy45C&^(BwV*E4hgwY3nJ`?!>5WI-qca# zrpJQZo7oB->qjd)>P~?z(5opdW$+qhBjmMiVPNJ_R2qzR;LDDBP^#oICmf}GJkp0C zuE|is7JP{q)B7oXbNM<4M$>vPuv_ zaXnQpB@)Lai7vTTR506sV~;QOhS6yz#Pl3NP=&f$I&xsvgW3%T

Fo6-3i^0i2sjjLV%xB!Oo$cmva}$_Do-qkwFZmz~D16Dx#v1f6?j1Oh zEVaZ^sv45SL+|~sr0{g@U+~m6A)p7|>>ndMFY$F{05d#SUXyy?%k=GGT16AoFqA!k za>0;TUp-y&YBkKJZrs)|_K3!^3m=L@z_N$Hv(`)poX2TyPm{Q}QjlV(wUXq_Tt{vg zgD&0<%$V3X+WT?&&uVw$+H{)-2i3>=ri5O+7~4PDCs|o*L$rfgvTMTONc5oV^g-Ry zgd@@C#=GsGRwSx@5P^bYjO1P9FxEJWAhYi*p+(lZpo@L--tH2z%MT>XXf^9Cc|CZY^gccBj;nu|G(yXXNR!K%azO;2?ERw?~ zU+^bE(V}VVHl5`+HZhCvX{}^{nT1Bb)RctLjWCiyG=)vx>Ct1bt@f!~E9~F|lnyU> zi(h4F$#6SZcJ*6RN8c9Vr(sN)V`Dt2*nnV#_wTv%K35Y_7&ou&+4XYj{qj0|kI0|R zE9)Y0X%%9OKlTVMi>24gU5gE>^~Hdq0LI6zU|8%%Sd zpqCvGaW?l{{W-Tm&r67l4?}Fd6XuQL$;*ny?)5fUW^e3Wy@Z9!U>|==lMiU#qU|3Sr`in%!Sl06B`HFTSK5$5|2v(P6&3cN? zzs@G?%kin;abs~U+-Wun#nxh`6Veh(R2l<55h<)0mFOUSDAFxUUKnJQHt^N1?uHj~ zFx*pDOr2q!F>5lI!e`l3SiuG_0L?3M>!@PpdEZfVnKYIv9t~Z(ngUh;@h&25ZOq4T zT_nT`8Tp2u$Kn{`w0JVBpB@KaQ+!EyqH3<9Smj`-Jk_4Wgmqe&I`&D4PX8U>5^C{q z_U9wFW(Y^M>ussD3o)V-H>B%@@fbI7J$U8*3o%NG;0w;!Ob+QW!7c~I{;&|SSL&Ry zJZ~b)Nn+4T`8_t_62QHp_?#xSEl-Xk`7d@pl}^=&xCx8%q|30Y_9B(u&N5tVIF(>$_=ZE+ zOySXeZ9`l2sEqA^;X2KD(>!S(hQvC*<}t4@W|61S18>Voa(N}0eqzK z7xP!iBgxTt?}{<~V7A5;M1+$@WxxB62`lF27Y+wqeAjLUv&K>3ol~NXK4#{NUzX0> zo`qp4g(Jux5C-~!AKwDF4O-p?%iEs%i2s#ws!%K>;Jwa{s z)-%*KLC-)eUijtiVC(wwk-dY+3K=+pE4ys_k#D26i>D6kV~jp8C!S9u*!%EQbr7c8 zmoIgDks$(u3T)p5m3p&r;ea+uZ~v`;U-3?d6Q77*ykIs!}WwQhe-(szPojzb4VW2x0q-I zK7+fdEX%}!3dTSb3Z)*QcT zeucoCH_<4OA<5gstM3aGALuh{5aVNF8@AMNlP-BBA5>S8zx_z~_)Ih-&z|6I`&U2M zE2_M1VOqn*u%%X$sl*bWHzz}uWxBQ!1x7Ec#jOlQi5O`LM^DWYhxe5tjh{cz?ApUp zBXDk2Mh=p!kY*Mm7R&6VITTSkQeq^Qg3mnk4_l|ql$!W%8lAb7A-&#%a&7r4Ir@;Z zR{i#z>h%r;{tRJ6+4G9888;>IQ;C>n2w9>P;!mO(854|Z-vmzY(UE=AE?9v_8HSP-WYE}a{^OdYuJcJ3RMRE9ZP z=HZ-lPoE+Wb&mzF8b>CXEmrZ;RSMe zq3{W0BTrJ;8b!Y1ROnMAedv9~>sK8(O-`s&Rphlm<8))`zQe2~tBeo+iTXmmk`rr! zxylgF*=5e-V}s*K`s)z{TAq5ybKRh6gjxi>E8MxJ!XwRI)w@Jq?Bl*^kkL;cir9WZ}%o&XgdJyl3DqQW( z<_jebiH(at&qG|Yr3c#q#-u5|vhC}LQAJf+{*`i{0)4`!`w`5?*{|SlD)?m}qk?&? zaXO}qF;Y~yzaBbia0@(qeRJz~NWSPJscl-fnZiQj{%q(B%zu+JZ}k8zvZy}D)3#H3 zyz$)WIkJm%(QwW%t_@G3V1;SxGJZs7%BOCwFeU%sC1J8HCe4zC&T!1Bx9s33Go(*Rqv4IjTfmcUoh z;0>%Crkpj}=-E~qe=iE6oAWWr)X=u4;sLO2pUdZ4RN7#C6|yQ&8SxasZ&1DvtV=(FDPie6hY+05^3q?})2 z4@=NGhM$7pf)oz8Zj5Nc02AOI5PfL=zakHiqGoBW{v*TlNAQttHCm%ZY5Yt9)5zWxt-|o8Z#{ zJ|&c!Nb=h3bT$m03*55O&d+-hPDz+5ZnS$AYNf2|p{LI)c6^P>SB|;eB_tT{lDG$| z)L>1KB0nO?V0KsAy_a3}L3`WDw{*Z0E&I7EJO4>PSH#iI#D(LvD#R+M0VHA&jtZY4 zfim2(dUi+Cv1IT&mng3Zi*|hni#l*^vA$rV_fdF`0@fF3!_N5#$FEuEz}Wrb^T4XK z){zyh1@ui7i&lo!Fq{m=+4m+qLO4ttsB@?Gv}B*be#M|&_lV`OfhX+mxW1n zP58Gt?^c$!KeB`?rGJ)y92WNkq7bN7pI7}=0@9H>fDs-xV~o_*L6pn#>h|){)@1)ZjF$=k!UB zzcGFcRs%j;0q@9(c5`VTz0waA%urjZB8rwA`bv51krPUr4{~vk?yPj{23MVG^{i`U z@j>?Thq>*L6x;}ZusTgX0WT#36Ki!}6|*Qr$Zsx`+mJB>o;0&L9Rwwj*Z2qd+f98>z{2e{R3AjR;9y?4zG*m-~=)HSut z^t9Er%}p%~O>`~)lJf#3zSWejfJ6I9J{V*Gg`$_C+YB`y}jcUOEtV6pa(evF$vNEIl^L-ZTj^n&U0anI< zXw8qpw!8LJ^d2A}CZhXipoZmQ%u`_8WPu3}_l^eq3VVAGP#Y*M22P;w?KVr%L;aO6aWBbAQ7U!i88DhmKjka#?0Rl|FUeB(UJe+i55n1aN?`#=n|L%6&NNdyQ)1Iu0hK1_NUe1HHNC%6lj} zy1(%)Pof(B%O4LA($D?+ojLgH_i+q0|Lh4Tuvr#c4}houbl8u|*1M*(e?QN}!SOe) zu#DH5_#N>36u|F)=#Shrmy3H?x;p0C_x4rd-Y4n=AVREjfx3G>IQV}91u%pDA8`U& z`Xv%N5F-dNz`%&_tO9=d5#JAV(6Ki8bH_m}A>l0mu?GxzE`Ne^xR4rsoh! z!bn8{Url`ZQyu8e#!H_2U^Zrk_q*9Pfte5#Fg1Jwta^4w0e-n?-2>7CLhBz~9|Bj0 z^%U@m0(#Jp*lc0-7l?xfKpgzl`#Iz8!I9+-tWu<`ois=)C%L1{GL7bU=~1VoX4HL}C|fR;e#{h62=4iyFq3`Yqt z96!5zYjBVtFH4e`KZ@e~-2 zUtP~0$hQ2?)BjIy<$c~FD`I-#4Y-{EFdV;5?h;)0qTbmUTI#CXTAAJJe53@9p{zh0 zsR70T`|-y#0H3j;>)UoE-{;%8a$ zpDqD9_Ft{`pG*E3k{|k$|Lov?ZlgdIDDSS`{O`s869v=;#ek{_-eELr|2F&1hW}xJ zg%T(TRKo5K#8m%#&_8TY8mIu>9j)`fw13IbfpS2Vm+m-dt^cv=AI|TL0##1BgQfl# z_8%Q3P}4v)jqYf2ZT~Utj`lm_Ky`@ja9{p_`$v@s)HqP>pF3J#`|piY|62(Nlm;q# zb4SDP{0;4Y5;&kNP-&JsR%h2AS-Gd0pk()NfPV|FfSLv>^KnN)>-_`icZPuq zcHH6Oeuw*)d<7yiWiXBGFeLI#uyTK#ZG zwOaZk^{-k8P#S2?#vKju@K3b63=U8tXkNq}@%)d(--QLxoPs+Z($SwR{5!({)I89$ z@;jXO@t<)2Jvj#@gPw)mk#D~L|B!z<83Tobo{HST-<*5cj ayWxQbR{daLQow&9z|O?t5_mff_WuAcBjxM> literal 0 HcmV?d00001 diff --git a/src/antidote_crdt.app.src b/src/antidote_crdt.app.src new file mode 100644 index 000000000..8f96dd4f9 --- /dev/null +++ b/src/antidote_crdt.app.src @@ -0,0 +1,14 @@ +{application, antidote_crdt, + [ + {description, "An Erlang antidote_crdt library"}, + {vsn, "1"}, + {modules, [ + antidote_crdt + ]}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {env, []} + ]}. diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl new file mode 100644 index 000000000..c1e77581b --- /dev/null +++ b/src/antidote_crdt.erl @@ -0,0 +1,44 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% antidote_crdt.erl : behaviour for op-based CRDTs + + +-module(antidote_crdt). + +-include("antidote_crdt.hrl"). + +-callback new() -> crdt(). +-callback value(crdt()) -> value(). +-callback downstream(update(), crdt()) -> {ok, effect()} | {error, reason()}. +-callback update(effect(), crdt()) -> {ok, crdt()}. +-callback require_state_downstream(update()) -> boolean(). +-callback is_operation(update()) -> boolean(). %% Type check + +-callback equal(crdt(), crdt()) -> boolean(). +-callback to_binary(crdt()) -> binary(). +-callback from_binary(binary()) -> {ok, crdt()} | {error, reason()}. + +%% Following callbacks taken from riak_dt +%% Not sure if it is useful for antidote +%-callback stats(crdt()) -> [{atom(), number()}]. +%-callback stat(atom(), crdt()) -> number() | undefined. + +%% End of Module. diff --git a/src/antidote_crdt_counter.erl b/src/antidote_crdt_counter.erl new file mode 100644 index 000000000..b5d5d845b --- /dev/null +++ b/src/antidote_crdt_counter.erl @@ -0,0 +1,189 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% antidote_crdt_pncounter: A convergent, replicated, operation +%% based PN-Counter + +-module(antidote_crdt_counter). + +-behaviour(antidote_crdt). + +-include("antidote_crdt.hrl"). + +-export([ new/0, + new/1, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +%% @doc Create a new, empty 'pncounter()' +-spec new() -> pncounter(). +new() -> + 0. + +%% @doc Create 'pncounter()' with initial value +-spec new(integer()) -> pncounter(). +new(Value) when is_integer(Value) -> + Value; +new(_) -> + new(). + +%% @doc The single, total value of a `pncounter()' +-spec value(pncounter()) -> integer(). +value(PNCnt) when is_integer(PNCnt) -> + PNCnt. + +%% @doc Generate a downstream operation. +%% The first parameter is either `increment' or `decrement' or the two tuples +%% `{increment, pos_integer()}' or `{decrement, pos_integer()}'. The second parameter +%% is the pncounter (this parameter is not actually used). +-spec downstream(pncounter_update(), any()) -> {ok, pncounter_effect()}. +downstream(increment, _PNCnt) -> + {ok, {increment, 1}}; +downstream(decrement, _PNCnt) -> + {ok, {decrement, 1}}; +downstream({increment, By}, _PNCnt) -> + {ok, {increment, By}}; +downstream({decrement, By}, _PNCnt) -> + {ok, {decrement, By}}. + +%% @doc Update a `pncounter()'. The first argument is either the atom +%% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or +%% `{decrement, pos_integer()}'. +%% In the case of the former, the operation's amount +%% is `1'. Otherwise it is the value provided in the tuple's second element. +%% The 2nd argument is the `pncounter()' to update. +%% +%% returns the updated `pncounter()' +-spec update(pncounter_effect(), pncounter()) -> {ok, pncounter()}. +update({_IncrDecr, 0}, PNCnt) -> + {ok, PNCnt}; +update({increment, By}, PNCnt) when is_integer(By), By > 0 -> + {ok, increment_by(By, PNCnt)}; +update({increment, By}, PNCnt) when is_integer(By), By < 0 -> + {ok, decrement_by(-By, PNCnt)}; +update({decrement, By}, PNCnt) when is_integer(By), By > 0 -> + {ok, decrement_by(By, PNCnt)}; +update({decrement, By}, PNCnt) when is_integer(By), By < 0 -> + {ok, increment_by(-By, PNCnt)}. + +%% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both +%% of their positive and negative entries are equal. +-spec equal(pncounter(), pncounter()) -> boolean(). +equal(PNCnt1, PNCnt2) -> + PNCnt1 =:= PNCnt2. + +-spec to_binary(pncounter()) -> binary(). +to_binary(PNCounter) -> + term_to_binary(PNCounter). + +from_binary(Bin) -> + %% @TODO something smarter + {ok, binary_to_term(Bin)}. + +%% @doc The following operation verifies +%% that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(increment) -> true; +is_operation(decrement) -> true; +is_operation({increment, By}) when is_integer(By) -> true; +is_operation({decrement, By}) when is_integer(By)-> true; +is_operation(_) -> false. + +%% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt +%% to generate downstream effect +-spec require_state_downstream(update()) -> boolean(). +require_state_downstream(_) -> + false. + + +% Priv +-spec increment_by(pos_integer(), pncounter()) -> pncounter(). +increment_by(Increment, PNCnt) -> + PNCnt+Increment. + +-spec decrement_by(pos_integer(), pncounter()) -> pncounter(). +decrement_by(Decrement, PNCnt) -> + PNCnt-Decrement. + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). + +new_test() -> + ?assertEqual(0, new()). + +%% @doc test the correctness of `value()' function +value_test() -> + PNCnt = 4, + ?assertEqual(4, value(PNCnt1)). + +%% @doc test the correctness of increment without parameter. +update_increment_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update(increment, PNCnt0), + {ok, PNCnt2} = update({increment, 2}, PNCnt1), + {ok, PNCnt3} = update(increment, PNCnt2), + ?assertEqual(4, value(PNCnt3)). + +%% @doc test the correctness of increment by some numbers. +update_increment_by_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 7}, PNCnt0), + ?assertEqual(7, value(PNCnt1)). + +%% @doc test the correctness of decrement. +update_decrement_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 1}, PNCnt0), + {ok, PNCnt2} = update({increment, 2}, PNCnt1), + {ok, PNCnt3} = update({increment, 1}, PNCnt2), + {ok, PNCnt4} = update({decrement, 1}, PNCnt3), + ?assertEqual(3, value(PNCnt4)). + +update_negative_params_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({{increment, -7}, 1}, PNCnt0), + {ok, PNCnt2} = update({{decrement, -5}, 1}, PNCnt1), + ?assertEqual(-2, value(PNCnt2)). + +equal_test() -> + PNCnt1 = 4 + PNCnt2 = 2 + PNCnt3 = 2 + ?assertNot(equal(PNCnt1, PNCnt2)), + ?assert(equal(PNCnt2, PNCnt3)). + +binary_test() -> + PNCnt1 = 4, + BinaryPNCnt1 = to_binary(PNCnt1), + {ok, PNCnt2} = from_binary(BinaryPNCnt1), + ?assert(equal(PNCnt1, PNCnt2)). + +-endif. + + From c4409d526fdba20345c25810852cd7d45f9a2e58 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 10 May 2016 10:18:02 +0200 Subject: [PATCH 099/426] remove pncounter --- src/crdt_pncounter.erl | 244 ----------------------------------------- 1 file changed, 244 deletions(-) delete mode 100644 src/crdt_pncounter.erl diff --git a/src/crdt_pncounter.erl b/src/crdt_pncounter.erl deleted file mode 100644 index 9dc72b5c9..000000000 --- a/src/crdt_pncounter.erl +++ /dev/null @@ -1,244 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% crdt_pncounter: A convergent, replicated, operation based PN-Counter. -%% -%% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - - -%% @doc -%% An operation-based PN-Counter CRDT. -%% A PN-Counter is represented as two non-negative integers: one for increments -%% and one for decrements. The value of the counter is the difference between the -%% value of the positive counter and the value of the negative counter. -%% -%% As the data structure is operation-based, to issue an operation, one should -%% firstly call `generate_downstream/3' to get the downstream version of the -%% operation and then call `update/2'. -%% -%% This file is adapted from riak_dt_pncounter, a state-based implementation of -%% PN-Counter. -%% The changes are as follows: -%% 1. `generate_downstream/3' is added, as this is a requirement for op-based CRDTs. -%% For PN-Counter, there is actually little difference between their op-based and -%% state-based implementation. Having `generate_downstream/3' is merely to keep -%% the interface of op-based CRDTs compatible with each other. -%% 2. `merge/2' is removed. -%% -%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of -%% Convergent and Commutative Replicated Data Types. [http://hal.upmc.fr/inria-00555588/] -%% -%% @end - --module(crdt_pncounter). - --export([new/0, new/1, value/1, value/2, update/2, generate_downstream/3, to_binary/1, from_binary/1]). --export([equal/2, is_operation/1]). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). --endif. - --export_type([pncounter/0, pncounter_op/0, binary_pncounter/0]). - --opaque pncounter() :: {Inc::non_neg_integer(), Dec::non_neg_integer()}. --type binary_pncounter() :: binary(). --type pncounter_op() :: {riak_dt_gcounter:gcounter_op(), binary()} | decrement_op(). --type decrement_op() :: decrement | {decrement, pos_integer(), binary()}. --type pncounter_q() :: positive | negative. - -%% @doc Create a new, empty `pncounter()' --spec new() -> pncounter(). -new() -> - {0,0}. - -%% @doc Create a `pncounter()' with an initial `Value' for `Actor'. --spec new(integer()) -> pncounter(). -new(Value) when Value > 0 -> - update({{increment, Value}, unique(1)}, new()); -new(Value) when Value < 0 -> - update({decrement, Value * -1, unique(1)}, new()); -new(_Zero) -> - new(). - -%% @doc The single, total value of a `pncounter()' --spec value(pncounter()) -> integer(). -value(PNCnt) -> - {Inc, Dec} = PNCnt, - Inc-Dec. - -%% @doc query the parts of a `pncounter()' -%% valid queries are `positive' or `negative'. --spec value(pncounter_q(), pncounter()) -> integer(). -value(positive, PNCnt) -> - {Inc, _Dec} = PNCnt, - Inc; -value(negative, PNCnt) -> - {_Inc, Dec} = PNCnt, - Dec. - -%% @doc Generate a downstream operation. -%% The first parameter is either `increment' or `decrement' or the two tuples -%% `{increment, pos_integer()}' or `{decrement, pos_integer()}'. The second parameter -%% is the actor and the third parameter is the pncounter (both parameters are not actually used). -%% -%% Returns a tuple representing the downstream operation and a unique identifier. The unique -%% identifier is to ensure that the two same operations (e.g. two {increment, 1}) in a single -%% transaction will not be ingored, which is caused by our implementation. --spec generate_downstream(pncounter_op(), riak_dt:actor(), pncounter()) -> {ok, pncounter_op()}. -generate_downstream(increment, Actor, _PNCnt) -> - {ok, {{increment, 1}, unique(Actor)}}; -generate_downstream(decrement, Actor, _PNCnt) -> - {ok, {{decrement, 1}, unique(Actor)}}; -generate_downstream({increment, By}, Actor, _PNCnt) -> - {ok, {{increment, By}, unique(Actor)}}; -generate_downstream({decrement, By}, Actor, _PNCnt) -> - {ok, {{decrement, By}, unique(Actor)}}. - - -%% @doc Update a `pncounter()'. The first argument is either the atom -%% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or -%% `{decrement, pos_integer()}', followed by a unique token, which is not used here. -%% In the case of the former, the operation's amount -%% is `1'. Otherwise it is the value provided in the tuple's second element. -%% The 2nd argument is the `pncounter()' to update. -%% -%% returns the updated `pncounter()' --spec update(pncounter_op(), pncounter()) -> {ok, pncounter()}. -update({{_IncrDecr, 0}, _Token}, PNCnt) -> - {ok, PNCnt}; -update({{increment, By}, _Token}, PNCnt) when is_integer(By), By > 0 -> - {ok, increment_by(By, PNCnt)}; -update({{increment, By}, _Token}, PNCnt) when is_integer(By), By < 0 -> - {ok, decrement_by(-By, PNCnt)}; -update({{decrement, By}, _Token}, PNCnt) when is_integer(By), By > 0 -> - {ok, decrement_by(By, PNCnt)}; -update({{decrement, By}, _Token}, PNCnt) when is_integer(By), By < 0 -> - {ok, increment_by(-By, PNCnt)}. - - -%% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both -%% of their positive and negative entries are equal. --spec equal(pncounter(), pncounter()) -> boolean(). -equal({Inc1, Dec1}, {Inc2, Dec2}) -> - case Inc1 of - Inc2 -> - case Dec1 of - Dec2 -> - true; - _ -> - false - end; - _ -> - false - end. - --include_lib("riak_dt/include/riak_dt_tags.hrl"). --define(TAG, ?DT_PNCOUNTER_TAG). --define(V1_VERS, 1). --define(V2_VERS, 2). - --spec to_binary(pncounter()) -> binary_pncounter(). -to_binary(PNCounter) -> - %% @TODO something smarter - <>. - -from_binary(<>) -> - %% @TODO something smarter - binary_to_term(Bin). - -% Priv --spec increment_by(pos_integer(), pncounter()) -> pncounter(). -increment_by(Increment, PNCnt) -> - {Inc, Dec} = PNCnt, - {Inc+Increment, Dec}. - --spec decrement_by(pos_integer(), pncounter()) -> pncounter(). -decrement_by(Decrement, PNCnt) -> - {Inc, Dec} = PNCnt, - {Inc, Dec+Decrement}. - -unique(_Actor) -> - crypto:strong_rand_bytes(20). - -%% @doc The following operation verifies -%% that Operation is supported by this particular CRDT. --spec is_operation(term()) -> boolean(). -is_operation(Operation) -> - riak_dt_pncounter:is_operation(Operation). - -%% =================================================================== -%% EUnit tests -%% =================================================================== --ifdef(TEST). - -new_test() -> - ?assertEqual({0,0}, new()). - -%% @doc test the correctness of `value()' function -value_test() -> - PNCnt1 = {4,0}, - PNCnt2 = {8,4}, - PNCnt3 = {4,4}, - ?assertEqual(4, value(PNCnt1)), - ?assertEqual(4, value(PNCnt2)), - ?assertEqual(0, value(PNCnt3)). - -%% @doc test the correctness of increment without parameter. -update_increment_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({{increment, 1}, 1}, PNCnt0), - {ok, PNCnt2} = update({{increment, 2}, 1}, PNCnt1), - {ok, PNCnt3} = update({{increment, 1}, 1}, PNCnt2), - ?assertEqual({4,0}, PNCnt3). - -%% @doc test the correctness of increment by some numbers. -update_increment_by_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({{increment, 7}, 1}, PNCnt0), - ?assertEqual({7,0}, PNCnt1). - -%% @doc test the correctness of decrement. -update_decrement_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({{increment, 1}, 1}, PNCnt0), - {ok, PNCnt2} = update({{increment, 2}, 1}, PNCnt1), - {ok, PNCnt3} = update({{increment, 1}, 1}, PNCnt2), - {ok, PNCnt4} = update({{decrement, 1}, 1}, PNCnt3), - ?assertEqual({4,1}, PNCnt4). - -update_decrement_by_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({{increment, 7}, 1}, PNCnt0), - {ok, PNCnt2} = update({{decrement, 5}, 1}, PNCnt1), - ?assertEqual({7, 5}, PNCnt2). - -equal_test() -> - PNCnt1 = {4,2}, - PNCnt2 = {2,0}, - PNCnt3 = {2,0}, - ?assertNot(equal(PNCnt1, PNCnt2)), - ?assert(equal(PNCnt2, PNCnt3)). - -binary_test() -> - PNCnt1 = {4,2}, - BinaryPNCnt1 = to_binary(PNCnt1), - PNCnt2 = from_binary(BinaryPNCnt1), - ?assert(equal(PNCnt1, PNCnt2)). - --endif. From 620d49fc5fb05f3adc82a1e4fbdb18d59824af6c Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 10 May 2016 10:19:04 +0200 Subject: [PATCH 100/426] rename orset --- src/{crdt_orset.erl => antidote_crdt_orset.erl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{crdt_orset.erl => antidote_crdt_orset.erl} (100%) diff --git a/src/crdt_orset.erl b/src/antidote_crdt_orset.erl similarity index 100% rename from src/crdt_orset.erl rename to src/antidote_crdt_orset.erl From a1ab3123778e5971afa0742d9ca08d435a608e16 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 10 May 2016 10:50:45 +0200 Subject: [PATCH 101/426] modified orset to antidote_crdt behaviour --- src/antidote_crdt_orset.erl | 161 ++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 72 deletions(-) diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 6f82f71c0..8ffc178e4 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -23,7 +23,7 @@ %% @doc %% An operation-based Observed-Remove Set CRDT. %% As the data structure is operation-based, to issue an operation, one should -%% firstly call `generate_downstream/3' to get the downstream version of the +%% firstly call `generate_downstream/3' to get the downstream version of the %% operation and then call `update/2'. %% %% It provides five operations: add, which adds an element to a set; add_all, @@ -31,7 +31,7 @@ %% remove_all that removes a list of elements from the set; update, that contains %% a list of previous four commands. %% -%% This file is adapted from riak_dt_orset, a state-based implementation of +%% This file is adapted from riak_dt_orset, a state-based implementation of %% Observed-Remove Set. %% The changes are as follows: %% 1. `generate_downstream/3' is added, as this is necessary for op-based CRDTs. @@ -42,11 +42,29 @@ %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% %% @end --module(crdt_orset). - -%% API --export([new/0, value/1, generate_downstream/3, update/2, equal/2, - to_binary/1, from_binary/1, value/2, precondition_context/1, stats/1, stat/2, is_operation/1]). +-module(antidote_crdt_orset). + +-include("antidote_crdt.hrl"). + +%% Callbacks +-export([ new/0, + value/1, + value/2, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +%% Others +-export([ precondition_context/1, + stats/1 + ]). + +-behaviour(antidote_crdt). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -58,20 +76,18 @@ -type binary_orset() :: binary(). %% A binary that from_binary/1 will operate on. -type orset_op() :: {add, member()} | {remove, member()} | - {add_all, [member()]} | {remove_all, [member()]} | - {update, [orset_op()]}. + {add_all, [member()]} | {remove_all, [member()]}. --type actor() :: riak_dt:actor(). -type member() :: term(). -spec new() -> orset(). new() -> orddict:new(). -%% @doc -%% without parameter: return all existing elements in the `orset()' -%% {fragment, elem}: create and return a new `orset()' with all metadata -%% of an element +%% @doc +%% without parameter: return all existing elements in the `orset()' +%% {fragment, elem}: create and return a new `orset()' with all metadata +%% of an element %% {tokens, elem}: returns all uniques tokens of an element in the set -spec value(orset()) -> [member()]. value(ORDict) -> @@ -95,52 +111,51 @@ value({tokens, Elem}, ORSet) -> value(_,ORSet) -> value(ORSet). -%% @doc generate downstream operations. +%% @doc generate downstream operations. %% If the operation is add or add_all, generate unique tokens for each element -%% If the operation is remove or remove_all, fetches all unique tokens for +%% If the operation is remove or remove_all, fetches all unique tokens for %% these elements existing in the `orset()'. --spec generate_downstream(orset_op(), actor(), orset()) -> {ok, orset_op()}. -generate_downstream({add,Elem}, Actor, _ORDict) -> - Token = unique(Actor), +-spec downstream(orset_op(), orset()) -> {ok, orset_op()}. +downstream({add,Elem}, _ORDict) -> + Token = unique(), {ok, {add, {Elem,[Token]}}}; -generate_downstream({add_all,Elems}, Actor, _ORDict0) -> +downstream({add_all,Elems}, _ORDict0) -> DownstreamOp = lists:foldl(fun(Elem, Sum) -> - Token = unique(Actor), - Sum++[{Elem, [Token]}] - end, [], Elems), + Token = unique(), + Sum++[{Elem, [Token]}] + end, [], Elems), {ok, {add_all, DownstreamOp}}; -generate_downstream({remove, Elem}, _Actor, ORDict) -> +downstream({remove, Elem}, ORDict) -> ToRemove = value({tokens, Elem}, ORDict), {ok, {remove, {Elem, ToRemove}}}; -generate_downstream({remove_all,Elems}, _Actor, ORDict) -> - ToRemove = lists:foldl(fun(Elem, Sum) -> Sum++[{Elem, value({tokens, Elem}, ORDict)}] end, [], Elems), +downstream({remove_all,Elems}, ORDict) -> + ToRemove = lists:foldl(fun(Elem, Sum) -> + Sum++[{Elem, value({tokens, Elem}, ORDict)}] + end, [], Elems), {ok, {remove_all, ToRemove}}. - %% @doc apply downstream operations and update an `orset()'. %% The first parameter denotes this operation is for adding or removing elements. %% For add or add_all, the second element of the tuple is a list of elements and tokens to add %% For remove or remove_all, the second element of the tuple is a list of elements and their tokens %% to remove. %% For update, the second element of the tuple is a list of updates to apply, each of which can -%% either be add, add_all or remove, remove_all. --spec update(orset_op(), orset()) -> {ok, orset()} | - {error, {precondition ,{not_present, member()}}}. +%% either be add, add_all or remove, remove_all. +-spec update(orset_op(), orset()) -> + {ok, orset()} | + {error, {precondition ,{not_present, member()}}}. update({add, {Elem, [Token|_]}}, ORDict) -> add_elem(Elem,Token,ORDict); update({add_all,Elems}, ORDict0) -> OD = lists:foldl(fun(Elem,ORDict) -> - {ok, ORDict1} = update({add,Elem},ORDict), - ORDict1 - end, ORDict0, Elems), + {ok, ORDict1} = update({add,Elem},ORDict), + ORDict1 + end, ORDict0, Elems), {ok, OD}; update({remove, Elem}, ORDict) -> remove_elem(Elem, ORDict); update({remove_all,Elems}, ORDict0) -> - remove_elems(Elems, ORDict0); -update({update, Ops}, ORDict) -> - apply_ops(Ops, ORDict). - + remove_elems(Elems, ORDict0). -spec equal(orset(), orset()) -> boolean(). equal(ORDictA, ORDictB) -> @@ -204,14 +219,14 @@ remove_elem({Elem,RemoveTokens},ORDict) -> case orddict:find(Elem,ORDict) of {ok, Tokens} -> RestTokens = Tokens--RemoveTokens, - case RestTokens of + case RestTokens of [] -> {ok, orddict:erase(Elem, ORDict)}; - _ -> + _ -> {ok, orddict:store(Elem, Tokens--RemoveTokens, ORDict)} end; error -> - case RemoveTokens of + case RemoveTokens of [] -> {ok, ORDict}; _ -> @@ -227,16 +242,8 @@ remove_elems([Elem|Rest], ORDict) -> Error -> Error end. -apply_ops([], ORDict) -> - {ok, ORDict}; -apply_ops([Op | Rest], ORDict) -> - case update(Op, ORDict) of - {ok, ORDict1} -> apply_ops(Rest, ORDict1); - Error -> Error - end. - %% @doc generate a unique identifier (best-effort). -unique(_Actor) -> +unique() -> crypto:strong_rand_bytes(20). minimum_tokens(Tokens) -> @@ -247,21 +254,31 @@ minimum_tokens(Tokens) -> %% @doc The following operation verifies %% that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). -is_operation(Operation) -> - riak_dt_orset:is_operation(Operation). +is_operation({add, _Elem}) -> true; +is_operation({add_all, [_H|_T]}) -> true; +is_operation({remove, _Elem}) -> + true; +is_operation({remove_all, [_H|_T]}) -> true. + +require_state_downstream({add,_}) -> + false; +require_state_downstream({add_all,_}) -> + false; +require_state_downstream({remove,_}) -> true; +require_state_downstream({remove_all, _}) -> true. %% =================================================================== %% EUnit tests %% =================================================================== -ifdef(TEST). new_test() -> - ?assertEqual(orddict:new(), new()). + ?assertEqual(orddict:new(), new()). add_test() -> Set1 = new(), - {ok, DownstreamOp1} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, DownstreamOp1} = downstream({add, <<"foo">>}, Set1), ?assertMatch({add, {<<"foo">>, _}}, DownstreamOp1), - {ok, DownstreamOp2} = generate_downstream({add_all, [<<"li">>,<<"manu">>]}, 1, Set1), + {ok, DownstreamOp2} = downstream({add_all, [<<"li">>,<<"manu">>]}, Set1), ?assertMatch({add_all, [{<<"li">>, _}, {<<"manu">>, _}]}, DownstreamOp2), {ok, Set2} = update(DownstreamOp1, Set1), {_, Elem1} = DownstreamOp1, @@ -272,11 +289,11 @@ add_test() -> value_test() -> Set1 = new(), - {ok, DownstreamOp1} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, DownstreamOp1} = downstream({add, <<"foo">>}, Set1), ?assertEqual([], value(Set1)), {ok, Set2} = update(DownstreamOp1, Set1), ?assertEqual([<<"foo">>], value(Set2)), - {ok, DownstreamOp2} = generate_downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set2), + {ok, DownstreamOp2} = downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, Set2), {ok, Set3} = update(DownstreamOp2, Set2), ?assertEqual([<<"foo">>, <<"li">>, <<"manu">>], value(Set3)), @@ -290,41 +307,41 @@ value_test() -> remove_test() -> Set1 = new(), %% Add an element then remove it - {ok, Op1} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, Op1} = downstream({add, <<"foo">>}, 1, Set1), {ok, Set2} = update(Op1, Set1), ?assertEqual([<<"foo">>], value(Set2)), - {ok, Op2} = generate_downstream({remove, <<"foo">>}, 1, Set2), + {ok, Op2} = downstream({remove, <<"foo">>}, 1, Set2), {ok, Set3} = update(Op2, Set2), ?assertEqual([], value(Set3)), %% Add many elements then remove part - {ok, Op3} = generate_downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), + {ok, Op3} = downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, Set1), {ok, Set4} = update(Op3, Set1), ?assertEqual([<<"foo">>, <<"li">>, <<"manu">>], value(Set4)), - {ok, Op5} = generate_downstream({remove_all, [<<"foo">>, <<"li">>]},1 , Set4), + {ok, Op5} = downstream({remove_all, [<<"foo">>, <<"li">>]}, Set4), {ok, Set5} = update(Op5, Set4), ?assertEqual([<<"manu">>], value(Set5)), - + %% Remove more than current have - {ok, Op6} = generate_downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, 1, Set1), + {ok, Op6} = downstream({add_all, [<<"foo">>, <<"li">>,<<"manu">>]}, Set1), {ok, Set6} = update(Op6, Set1), - {ok, Op7} = generate_downstream({remove_all, [<<"manu">>, <<"test">>]}, 1, Set6), + {ok, Op7} = downstream({remove_all, [<<"manu">>, <<"test">>]}, Set6), Result = update(Op7, Set6), ?assertMatch({ok, _}, Result). - + concurrent_add_test() -> Set1 = new(), %% Add an element then remove it - {ok, Op1} = generate_downstream({add, <<"foo">>}, 1, Set1), + {ok, Op1} = downstream({add, <<"foo">>}, Set1), {ok, Set2} = update(Op1, Set1), ?assertEqual([<<"foo">>], value(Set2)), - - %% If remove is concurrent with the second add, will not remove the second added - {ok, Op2} = generate_downstream({remove, <<"foo">>}, 1, Set2), - {ok, Op3} = generate_downstream({add, <<"foo">>}, 1, Set1), + %% If remove is concurrent with the second add, will not remove the second added + {ok, Op2} = downstream({remove, <<"foo">>}, Set2), + + {ok, Op3} = downstream({add, <<"foo">>}, Set1), {ok, Set3} = update(Op3, Set2), ?assertEqual([<<"foo">>], value(Set3)), @@ -332,17 +349,17 @@ concurrent_add_test() -> ?assertEqual([<<"foo">>], value(Set4)), %% If remove follows two adds, remove will remove all - {ok, Op4} = generate_downstream({remove, <<"foo">>}, 1, Set3), + {ok, Op4} = downstream({remove, <<"foo">>}, Set3), {ok, Set5} = update(Op4, Set3), ?assertEqual([], value(Set5)). - + binary_test() -> ORSet1 = new(), BinaryORSet1 = to_binary(ORSet1), ORSet2 = from_binary(BinaryORSet1), ?assert(equal(ORSet1, ORSet2)), - {ok, Op1} = generate_downstream({add, <<"foo">>}, 1, ORSet1), + {ok, Op1} = downstream({add, <<"foo">>}, ORSet1), {ok, ORSet3} = update(Op1, ORSet1), BinaryORSet3 = to_binary(ORSet3), ORSet4 = from_binary(BinaryORSet3), From c5fe61715727718cd4bdf10ed9749effc49abd2a Mon Sep 17 00:00:00 2001 From: Deepthi Akkoorath Date: Tue, 10 May 2016 11:00:15 +0200 Subject: [PATCH 102/426] create README --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..6d38db4c2 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# antidote_crdt +CRDT implementations to use with Antidote From 74bbc62ccb2c924d893d5b62a2fd3f5563399500 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 10 May 2016 11:01:06 +0200 Subject: [PATCH 103/426] add rebar config --- rebar.config | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 rebar.config diff --git a/rebar.config b/rebar.config new file mode 100644 index 000000000..b00a0f5bb --- /dev/null +++ b/rebar.config @@ -0,0 +1,11 @@ +{lib_dirs,["deps"]}. + +{deps, [ + {riak_dt, ".*", {git, "git://github.com/aletomsic/riak_dt", {tag, "type_check_antidote"}}} + ]}. + +{cover_enabled, true}. +{erl_opts, [debug_info, warnings_as_errors, {platform_define, "^[0-9]+", namespaced_types}]}. +{eunit_opts, [verbose]}. +{xref_checks, [undefined_function_calls]}. +{edoc_opts, [{preprocess, true}]}. From ea5fe7ab0c252617a572a1ec1f3027d7f1ed9204 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 10 May 2016 14:30:22 +0200 Subject: [PATCH 104/426] fix eunit test --- src/antidote_crdt_counter.erl | 20 ++++++++++++-------- src/antidote_crdt_orset.erl | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/antidote_crdt_counter.erl b/src/antidote_crdt_counter.erl index b5d5d845b..d2ce6d49f 100644 --- a/src/antidote_crdt_counter.erl +++ b/src/antidote_crdt_counter.erl @@ -27,6 +27,10 @@ -include("antidote_crdt.hrl"). +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + -export([ new/0, new/1, value/1, @@ -140,14 +144,14 @@ new_test() -> %% @doc test the correctness of `value()' function value_test() -> PNCnt = 4, - ?assertEqual(4, value(PNCnt1)). + ?assertEqual(4, value(PNCnt)). %% @doc test the correctness of increment without parameter. update_increment_test() -> PNCnt0 = new(), - {ok, PNCnt1} = update(increment, PNCnt0), + {ok, PNCnt1} = update({increment, 1}, PNCnt0), {ok, PNCnt2} = update({increment, 2}, PNCnt1), - {ok, PNCnt3} = update(increment, PNCnt2), + {ok, PNCnt3} = update({increment, 1}, PNCnt2), ?assertEqual(4, value(PNCnt3)). %% @doc test the correctness of increment by some numbers. @@ -167,14 +171,14 @@ update_decrement_test() -> update_negative_params_test() -> PNCnt0 = new(), - {ok, PNCnt1} = update({{increment, -7}, 1}, PNCnt0), - {ok, PNCnt2} = update({{decrement, -5}, 1}, PNCnt1), + {ok, PNCnt1} = update({increment, -7}, PNCnt0), + {ok, PNCnt2} = update({decrement, -5}, PNCnt1), ?assertEqual(-2, value(PNCnt2)). equal_test() -> - PNCnt1 = 4 - PNCnt2 = 2 - PNCnt3 = 2 + PNCnt1 = 4, + PNCnt2 = 2, + PNCnt3 = 2, ?assertNot(equal(PNCnt1, PNCnt2)), ?assert(equal(PNCnt2, PNCnt3)). diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 8ffc178e4..f92dfebc3 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -307,10 +307,10 @@ value_test() -> remove_test() -> Set1 = new(), %% Add an element then remove it - {ok, Op1} = downstream({add, <<"foo">>}, 1, Set1), + {ok, Op1} = downstream({add, <<"foo">>}, Set1), {ok, Set2} = update(Op1, Set1), ?assertEqual([<<"foo">>], value(Set2)), - {ok, Op2} = downstream({remove, <<"foo">>}, 1, Set2), + {ok, Op2} = downstream({remove, <<"foo">>}, Set2), {ok, Set3} = update(Op2, Set2), ?assertEqual([], value(Set3)), From fe22709b524b66af8c4b8a6ea7045fe7fa4e0182 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 12 May 2016 13:43:36 +0200 Subject: [PATCH 105/426] rename rga --- src/antidote_crdt_rga.erl | 296 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 src/antidote_crdt_rga.erl diff --git a/src/antidote_crdt_rga.erl b/src/antidote_crdt_rga.erl new file mode 100644 index 000000000..5656675cb --- /dev/null +++ b/src/antidote_crdt_rga.erl @@ -0,0 +1,296 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2015 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc +%% +%% An operation-based Replicated Growable Array CRDT. +%% +%% As the data structure is operation-based, to issue an operation, one should +%% first call `generate_downstream/3', to get the downstream version of the +%% operation, and then call `update/2'. +%% +%% It provides two operations: addRight, which adds an element to the RGA, and remove, +%% which removes an element from the RGA. +%% +%% This implementation is based on the paper cited below. +%% +%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of +%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ +%% +%% @end +-module(crdt_rga). + +-export([new/0, update/2, purge_tombstones/1, generate_downstream/3, value/1, is_operation/1]). + +-export_type([rga/0, rga_op/0, rga_downstream_op/0]). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-type vertex() :: {ok | deleted, any(), number()}. + +-type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, {ok, any(), number()}}. + +-type rga_op() :: {addRight, any(), non_neg_integer()} | {remove, non_neg_integer()}. + +-type rga_result() :: {ok, rga()}. + +-type rga() :: [vertex()]. + +-type actor() :: riak_dt:actor(). + +-spec new() -> []. +new() -> + []. + +%% @doc generate downstream operations. +%% If the operation is addRight, generates a unique token for the new element. +%% If the operation is remove, fetches the vertex of the element to be removed. +-spec generate_downstream(rga_op(), actor(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. +generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> + case (Position < 0) or (Position > length(Rga)) of + true -> {error, {invalid_position, Position}}; + false -> case (Rga == []) or (Position == 0) of + true -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; + false -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} + end + end; +generate_downstream({remove, Position}, _Actor, Rga) -> + {ok, {remove, lists:nth(Position, Rga)}}. + +%% @doc given an RGA, returns the same RGA, as it represents its own value. +-spec value(rga()) -> rga(). +value(Rga) -> + Rga. + +%% @doc This method takes in an rga operation and an rga to perform the operation. +%% It returns either the added Vertex and the new rga in case of an addRight, and the new rga in the case of a remove. +-spec update(rga_downstream_op(), rga()) -> rga_result(). +update({addRight, RightVertex, NewVertex}, Rga) -> + recursive_insert(RightVertex, NewVertex, Rga, []); +update({remove, Vertex}, Rga) -> + remove_vertex(Vertex, Rga). + +%% Private +%% @doc recursively looks for the Vertex where the new element should be put to the right of. +-spec recursive_insert(vertex(), vertex(), rga(), list()) -> rga_result(). +recursive_insert(_, NewVertex, [], []) -> + {ok, [NewVertex]}; +recursive_insert({ok, 0, 0}, NewVertex, L, []) -> + add_element(NewVertex, L, []); +recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> + add_element(NewVertex, T, [RightVertex | L]); +recursive_insert(RightVertex, NewVertex, [H | T], L) -> + recursive_insert(RightVertex, NewVertex, T, [H | L]). + +%% Private +%% @doc the place for the insertion has been found, so now the UIDs are compared to see where to insert. +-spec add_element(vertex(), rga(), list()) -> rga_result(). +add_element({Status, Value, UID}, [{Status1, Value1, UID1} | T], L) -> + case UID >= UID1 of + true -> + {ok, lists:reverse(L) ++ [{Status, Value, UID}] ++ [{Status1, Value1, UID1} | T]}; + _ -> + add_element({Status, Value, UID}, T, [{Status1, Value1, UID1} | L]) + end; +add_element(Insert, [], L) -> + {ok, lists:reverse([Insert | L])}. + +%% Private +%% @doc looks for the Vertex to be removed. Once it's found, it's marked as "deleted". +%% The Vertex is not removed from the list, to allow adding elements to its right. +-spec remove_vertex(vertex(), rga()) -> rga_result(). +remove_vertex({ok, Value, UID}, Rga) -> + {ok, lists:keyreplace(UID, 3, Rga, {deleted, Value, UID})}. + +%% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. +-spec purge_tombstones(rga()) -> rga_result(). +purge_tombstones(Rga) -> + L = lists:filter(fun({Status, _, _}) -> Status == ok end, Rga), + {ok, L}. + +%% @doc generates a unique identifier based on the node and a unique reference. +unique() -> + {node(), make_ref()}. + +%% @doc The following operation verifies that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(Operation) -> + case Operation of + {addRight, _, Position} -> + (is_integer(Position) and (Position >= 0)); + {remove, Position} -> + (is_integer(Position) and (Position >= 0)); + _ -> + false + end. + + +-ifdef(TEST). + +new_test() -> + ?assertEqual([], new()). + +generate_downstream_invalid_position_test() -> + L = new(), + Result1 = generate_downstream({addRight, 1, 1}, 1, L), + ?assertMatch({error, {invalid_position, 1}}, Result1), + Result2 = generate_downstream({addRight, 1, -1}, 1, L), + ?assertMatch({error, {invalid_position, -1}}, Result2). + +generate_downstream_empty_rga_test() -> + L = new(), + {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), + ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). + +generate_downstream_non_empty_rga_test() -> + L = new(), + {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), + {ok, L1} = update(DownstreamOp, L), + {ok, DownstreamOp1} = generate_downstream({addRight, 3, 1}, 1, L1), + ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). + +add_right_in_empty_rga_test() -> + L = new(), + {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), + {ok, L1} = update(DownstreamOp, L), + ?assertMatch([{ok, 1, _}], L1). + +add_right_in_non_empty_rga_test() -> + L = new(), + {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), + {ok, L1} = update(DownstreamOp, L), + {ok, DownstreamOp1} = generate_downstream({addRight, 2, 1}, 1, L1), + {ok, L2} = update(DownstreamOp1, L1), + ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). + +%% In the tests that follow, the values of generate_downstream are placed by hand ,so +%% the intended scenarios can be correctly tested, not depending on the unique() function. + +insert_in_the_middle_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + ?assertMatch([{ok, 1, _}, {ok, 2, _}, {ok, 3, _}], L3). + +remove_first_element_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 1}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), + ?assertMatch([{deleted, 1, _}, {ok, 2, _}, {ok, 3, _}], L4). + +remove_middle_element_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), + ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 3, _}], L4). + +remove_last_element_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 3}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), + ?assertMatch([{ok, 1, _}, {ok, 2, _}, {deleted, 3, _}], L4). + +insert_right_of_a_remove_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 4}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), + DownstreamOp5 = {addRight, {deleted, 2, 4}, {ok, 4, 3}}, + {ok, L5} = update(DownstreamOp5, L4), + ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 4, _}, {ok, 3, _}], L5). + +purge_tombstones_test() -> + L = new(), + DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, + DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, + DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, + {ok, L1} = update(DownstreamOp1, L), + {ok, L2} = update(DownstreamOp2, L1), + {ok, L3} = update(DownstreamOp3, L2), + {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, L4} = update(DownstreamOp4, L3), + {ok, L5} = purge_tombstones(L4), + ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). + +%% This test creates two RGAs and performs updates, checking they reach +%% the same final state after the four updates are aplied in both replicas. +concurrent_updates_in_two_replicas_test() -> + R1_0 = new(), + R2_0 = new(), + {ok, DownstreamOp1} = generate_downstream({addRight, 1, 0}, 1, R1_0), + {ok, DownstreamOp2} = generate_downstream({addRight, 2, 0}, 1, R2_0), + {ok, R1_1} = update(DownstreamOp1, R1_0), + {ok, R2_1} = update(DownstreamOp2, R2_0), + {ok, R1_2} = update(DownstreamOp2, R1_1), + {ok, R2_2} = update(DownstreamOp1, R2_1), + ?assertEqual(R1_2, R2_2), + {ok, DownstreamOp3} = generate_downstream({addRight, 3, 2}, 1, R1_2), + {ok, DownstreamOp4} = generate_downstream({addRight, 4, 2}, 1, R2_2), + {ok, R1_3} = update(DownstreamOp3, R1_2), + {ok, R2_3} = update(DownstreamOp4, R2_2), + {ok, R1_4} = update(DownstreamOp4, R1_3), + {ok, R2_4} = update(DownstreamOp3, R2_3), + ?assertEqual(R1_4, R2_4). + +is_operation_test() -> + %% addRight checks + ?assertEqual(false, is_operation({addRight, value, -1})), + ?assertEqual(true, is_operation({addRight, value, 0})), + ?assertEqual(true, is_operation({addRight, value, 1})), + + %% remove checks + ?assertEqual(false, is_operation({remove, -1})), + ?assertEqual(true, is_operation({remove, 0})), + ?assertEqual(true, is_operation({remove, 1})), + + %% invalid operation checks + ?assertEqual(false, is_operation({anything, 1})), + ?assertEqual(false, is_operation({add, 1, 4})). + +-endif. From 614b2bd2c466b0422a7935d1bdd2d6d21cc4d2bf Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 12 May 2016 14:06:56 +0200 Subject: [PATCH 106/426] rga antidote_crdt behaviour --- src/antidote_crdt_rga.erl | 84 ++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/src/antidote_crdt_rga.erl b/src/antidote_crdt_rga.erl index 5656675cb..67f83278c 100644 --- a/src/antidote_crdt_rga.erl +++ b/src/antidote_crdt_rga.erl @@ -35,9 +35,23 @@ %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% %% @end --module(crdt_rga). +-module(antidote_crdt_rga). --export([new/0, update/2, purge_tombstones/1, generate_downstream/3, value/1, is_operation/1]). +-behaviour(antidote_crdt). + +%% Call backs +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +-export([purge_tombstones/1]). -export_type([rga/0, rga_op/0, rga_downstream_op/0]). @@ -55,8 +69,6 @@ -type rga() :: [vertex()]. --type actor() :: riak_dt:actor(). - -spec new() -> []. new() -> []. @@ -64,8 +76,8 @@ new() -> %% @doc generate downstream operations. %% If the operation is addRight, generates a unique token for the new element. %% If the operation is remove, fetches the vertex of the element to be removed. --spec generate_downstream(rga_op(), actor(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. -generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> +-spec downstream(rga_op(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. +downstream({addRight, Elem, Position}, Rga) -> case (Position < 0) or (Position > length(Rga)) of true -> {error, {invalid_position, Position}}; false -> case (Rga == []) or (Position == 0) of @@ -73,7 +85,7 @@ generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> false -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} end end; -generate_downstream({remove, Position}, _Actor, Rga) -> +downstream({remove, Position}, Rga) -> {ok, {remove, lists:nth(Position, Rga)}}. %% @doc given an RGA, returns the same RGA, as it represents its own value. @@ -133,16 +145,24 @@ unique() -> %% @doc The following operation verifies that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). -is_operation(Operation) -> - case Operation of - {addRight, _, Position} -> - (is_integer(Position) and (Position >= 0)); - {remove, Position} -> +is_operation({addRight, _, Position}) -> + (is_integer(Position) and (Position >= 0)); +is_operation({remove, Position})-> (is_integer(Position) and (Position >= 0)); - _ -> - false - end. +is_operation(_) -> + false. + +require_state_downstream(_) -> + true. + +equal(Rga1, Rga2) -> + Rga1 == Rga2. + +to_binary(Rga1) -> + erlang:term_to_binary(Rga1). +from_binary(Bin) -> + {ok, erlang:binary_to_term(Bin)}. -ifdef(TEST). @@ -151,34 +171,34 @@ new_test() -> generate_downstream_invalid_position_test() -> L = new(), - Result1 = generate_downstream({addRight, 1, 1}, 1, L), + Result1 = downstream({addRight, 1, 1}, L), ?assertMatch({error, {invalid_position, 1}}, Result1), - Result2 = generate_downstream({addRight, 1, -1}, 1, L), + Result2 = downstream({addRight, 1, -1}, L), ?assertMatch({error, {invalid_position, -1}}, Result2). generate_downstream_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), + {ok, DownstreamOp} = downstream({addRight, 4, 0}, L), ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). generate_downstream_non_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), + {ok, DownstreamOp} = downstream({addRight, 4, 0}, L), {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = generate_downstream({addRight, 3, 1}, 1, L1), + {ok, DownstreamOp1} = downstream({addRight, 3, 1}, L1), ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). add_right_in_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), + {ok, DownstreamOp} = downstream({addRight, 1, 0}, L), {ok, L1} = update(DownstreamOp, L), ?assertMatch([{ok, 1, _}], L1). add_right_in_non_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), + {ok, DownstreamOp} = downstream({addRight, 1, 0}, L), {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = generate_downstream({addRight, 2, 1}, 1, L1), + {ok, DownstreamOp1} = downstream({addRight, 2, 1}, L1), {ok, L2} = update(DownstreamOp1, L1), ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). @@ -203,7 +223,7 @@ remove_first_element_test() -> {ok, L1} = update(DownstreamOp1, L), {ok, L2} = update(DownstreamOp2, L1), {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 1}, 1, L3), + {ok, DownstreamOp4} = downstream({remove, 1}, L3), {ok, L4} = update(DownstreamOp4, L3), ?assertMatch([{deleted, 1, _}, {ok, 2, _}, {ok, 3, _}], L4). @@ -215,7 +235,7 @@ remove_middle_element_test() -> {ok, L1} = update(DownstreamOp1, L), {ok, L2} = update(DownstreamOp2, L1), {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, DownstreamOp4} = downstream({remove, 2}, L3), {ok, L4} = update(DownstreamOp4, L3), ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 3, _}], L4). @@ -227,7 +247,7 @@ remove_last_element_test() -> {ok, L1} = update(DownstreamOp1, L), {ok, L2} = update(DownstreamOp2, L1), {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 3}, 1, L3), + {ok, DownstreamOp4} = downstream({remove, 3}, L3), {ok, L4} = update(DownstreamOp4, L3), ?assertMatch([{ok, 1, _}, {ok, 2, _}, {deleted, 3, _}], L4). @@ -239,7 +259,7 @@ insert_right_of_a_remove_test() -> {ok, L1} = update(DownstreamOp1, L), {ok, L2} = update(DownstreamOp2, L1), {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, DownstreamOp4} = downstream({remove, 2}, L3), {ok, L4} = update(DownstreamOp4, L3), DownstreamOp5 = {addRight, {deleted, 2, 4}, {ok, 4, 3}}, {ok, L5} = update(DownstreamOp5, L4), @@ -253,7 +273,7 @@ purge_tombstones_test() -> {ok, L1} = update(DownstreamOp1, L), {ok, L2} = update(DownstreamOp2, L1), {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), + {ok, DownstreamOp4} = downstream({remove, 2}, L3), {ok, L4} = update(DownstreamOp4, L3), {ok, L5} = purge_tombstones(L4), ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). @@ -263,15 +283,15 @@ purge_tombstones_test() -> concurrent_updates_in_two_replicas_test() -> R1_0 = new(), R2_0 = new(), - {ok, DownstreamOp1} = generate_downstream({addRight, 1, 0}, 1, R1_0), - {ok, DownstreamOp2} = generate_downstream({addRight, 2, 0}, 1, R2_0), + {ok, DownstreamOp1} = downstream({addRight, 1, 0}, R1_0), + {ok, DownstreamOp2} = downstream({addRight, 2, 0}, R2_0), {ok, R1_1} = update(DownstreamOp1, R1_0), {ok, R2_1} = update(DownstreamOp2, R2_0), {ok, R1_2} = update(DownstreamOp2, R1_1), {ok, R2_2} = update(DownstreamOp1, R2_1), ?assertEqual(R1_2, R2_2), - {ok, DownstreamOp3} = generate_downstream({addRight, 3, 2}, 1, R1_2), - {ok, DownstreamOp4} = generate_downstream({addRight, 4, 2}, 1, R2_2), + {ok, DownstreamOp3} = downstream({addRight, 3, 2}, R1_2), + {ok, DownstreamOp4} = downstream({addRight, 4, 2}, R2_2), {ok, R1_3} = update(DownstreamOp3, R1_2), {ok, R2_3} = update(DownstreamOp4, R2_2), {ok, R1_4} = update(DownstreamOp4, R1_3), From a6bbc232af90a847d9de5e572ae3b58b7f6d6d5a Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 12 May 2016 14:09:36 +0200 Subject: [PATCH 107/426] rename bcounter --- ...counter.erl => antidote_crdt_bcounter.erl} | 0 src/crdt_rga.erl | 296 ------------------ 2 files changed, 296 deletions(-) rename src/{crdt_bcounter.erl => antidote_crdt_bcounter.erl} (100%) delete mode 100644 src/crdt_rga.erl diff --git a/src/crdt_bcounter.erl b/src/antidote_crdt_bcounter.erl similarity index 100% rename from src/crdt_bcounter.erl rename to src/antidote_crdt_bcounter.erl diff --git a/src/crdt_rga.erl b/src/crdt_rga.erl deleted file mode 100644 index 5656675cb..000000000 --- a/src/crdt_rga.erl +++ /dev/null @@ -1,296 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% Copyright (c) 2015 SyncFree Consortium. All Rights Reserved. -%% -%% This file is provided to you under the Apache License, -%% Version 2.0 (the "License"); you may not use this file -%% except in compliance with the License. You may obtain -%% a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, -%% software distributed under the License is distributed on an -%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -%% KIND, either express or implied. See the License for the -%% specific language governing permissions and limitations -%% under the License. -%% -%% ------------------------------------------------------------------- - -%% @doc -%% -%% An operation-based Replicated Growable Array CRDT. -%% -%% As the data structure is operation-based, to issue an operation, one should -%% first call `generate_downstream/3', to get the downstream version of the -%% operation, and then call `update/2'. -%% -%% It provides two operations: addRight, which adds an element to the RGA, and remove, -%% which removes an element from the RGA. -%% -%% This implementation is based on the paper cited below. -%% -%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of -%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ -%% -%% @end --module(crdt_rga). - --export([new/0, update/2, purge_tombstones/1, generate_downstream/3, value/1, is_operation/1]). - --export_type([rga/0, rga_op/0, rga_downstream_op/0]). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). --endif. - --type vertex() :: {ok | deleted, any(), number()}. - --type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, {ok, any(), number()}}. - --type rga_op() :: {addRight, any(), non_neg_integer()} | {remove, non_neg_integer()}. - --type rga_result() :: {ok, rga()}. - --type rga() :: [vertex()]. - --type actor() :: riak_dt:actor(). - --spec new() -> []. -new() -> - []. - -%% @doc generate downstream operations. -%% If the operation is addRight, generates a unique token for the new element. -%% If the operation is remove, fetches the vertex of the element to be removed. --spec generate_downstream(rga_op(), actor(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. -generate_downstream({addRight, Elem, Position}, _Actor, Rga) -> - case (Position < 0) or (Position > length(Rga)) of - true -> {error, {invalid_position, Position}}; - false -> case (Rga == []) or (Position == 0) of - true -> {ok, {addRight, {ok, 0, 0}, {ok, Elem, unique()}}}; - false -> {ok, {addRight, lists:nth(Position, Rga), {ok, Elem, unique()}}} - end - end; -generate_downstream({remove, Position}, _Actor, Rga) -> - {ok, {remove, lists:nth(Position, Rga)}}. - -%% @doc given an RGA, returns the same RGA, as it represents its own value. --spec value(rga()) -> rga(). -value(Rga) -> - Rga. - -%% @doc This method takes in an rga operation and an rga to perform the operation. -%% It returns either the added Vertex and the new rga in case of an addRight, and the new rga in the case of a remove. --spec update(rga_downstream_op(), rga()) -> rga_result(). -update({addRight, RightVertex, NewVertex}, Rga) -> - recursive_insert(RightVertex, NewVertex, Rga, []); -update({remove, Vertex}, Rga) -> - remove_vertex(Vertex, Rga). - -%% Private -%% @doc recursively looks for the Vertex where the new element should be put to the right of. --spec recursive_insert(vertex(), vertex(), rga(), list()) -> rga_result(). -recursive_insert(_, NewVertex, [], []) -> - {ok, [NewVertex]}; -recursive_insert({ok, 0, 0}, NewVertex, L, []) -> - add_element(NewVertex, L, []); -recursive_insert(RightVertex, NewVertex, [RightVertex | T], L) -> - add_element(NewVertex, T, [RightVertex | L]); -recursive_insert(RightVertex, NewVertex, [H | T], L) -> - recursive_insert(RightVertex, NewVertex, T, [H | L]). - -%% Private -%% @doc the place for the insertion has been found, so now the UIDs are compared to see where to insert. --spec add_element(vertex(), rga(), list()) -> rga_result(). -add_element({Status, Value, UID}, [{Status1, Value1, UID1} | T], L) -> - case UID >= UID1 of - true -> - {ok, lists:reverse(L) ++ [{Status, Value, UID}] ++ [{Status1, Value1, UID1} | T]}; - _ -> - add_element({Status, Value, UID}, T, [{Status1, Value1, UID1} | L]) - end; -add_element(Insert, [], L) -> - {ok, lists:reverse([Insert | L])}. - -%% Private -%% @doc looks for the Vertex to be removed. Once it's found, it's marked as "deleted". -%% The Vertex is not removed from the list, to allow adding elements to its right. --spec remove_vertex(vertex(), rga()) -> rga_result(). -remove_vertex({ok, Value, UID}, Rga) -> - {ok, lists:keyreplace(UID, 3, Rga, {deleted, Value, UID})}. - -%% @doc given an rga, this mehtod looks for all tombstones and removes them, returning the tombstone free rga. --spec purge_tombstones(rga()) -> rga_result(). -purge_tombstones(Rga) -> - L = lists:filter(fun({Status, _, _}) -> Status == ok end, Rga), - {ok, L}. - -%% @doc generates a unique identifier based on the node and a unique reference. -unique() -> - {node(), make_ref()}. - -%% @doc The following operation verifies that Operation is supported by this particular CRDT. --spec is_operation(term()) -> boolean(). -is_operation(Operation) -> - case Operation of - {addRight, _, Position} -> - (is_integer(Position) and (Position >= 0)); - {remove, Position} -> - (is_integer(Position) and (Position >= 0)); - _ -> - false - end. - - --ifdef(TEST). - -new_test() -> - ?assertEqual([], new()). - -generate_downstream_invalid_position_test() -> - L = new(), - Result1 = generate_downstream({addRight, 1, 1}, 1, L), - ?assertMatch({error, {invalid_position, 1}}, Result1), - Result2 = generate_downstream({addRight, 1, -1}, 1, L), - ?assertMatch({error, {invalid_position, -1}}, Result2). - -generate_downstream_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), - ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). - -generate_downstream_non_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 4, 0}, 1, L), - {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = generate_downstream({addRight, 3, 1}, 1, L1), - ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). - -add_right_in_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), - {ok, L1} = update(DownstreamOp, L), - ?assertMatch([{ok, 1, _}], L1). - -add_right_in_non_empty_rga_test() -> - L = new(), - {ok, DownstreamOp} = generate_downstream({addRight, 1, 0}, 1, L), - {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = generate_downstream({addRight, 2, 1}, 1, L1), - {ok, L2} = update(DownstreamOp1, L1), - ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). - -%% In the tests that follow, the values of generate_downstream are placed by hand ,so -%% the intended scenarios can be correctly tested, not depending on the unique() function. - -insert_in_the_middle_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - ?assertMatch([{ok, 1, _}, {ok, 2, _}, {ok, 3, _}], L3). - -remove_first_element_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 1}, 1, L3), - {ok, L4} = update(DownstreamOp4, L3), - ?assertMatch([{deleted, 1, _}, {ok, 2, _}, {ok, 3, _}], L4). - -remove_middle_element_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), - {ok, L4} = update(DownstreamOp4, L3), - ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 3, _}], L4). - -remove_last_element_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 3}, 1, L3), - {ok, L4} = update(DownstreamOp4, L3), - ?assertMatch([{ok, 1, _}, {ok, 2, _}, {deleted, 3, _}], L4). - -insert_right_of_a_remove_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 4}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), - {ok, L4} = update(DownstreamOp4, L3), - DownstreamOp5 = {addRight, {deleted, 2, 4}, {ok, 4, 3}}, - {ok, L5} = update(DownstreamOp5, L4), - ?assertMatch([{ok, 1, _}, {deleted, 2, _}, {ok, 4, _}, {ok, 3, _}], L5). - -purge_tombstones_test() -> - L = new(), - DownstreamOp1 = {addRight, {ok, 0, 0}, {ok, 1, 1}}, - DownstreamOp2 = {addRight, {ok, 1, 1}, {ok, 3, 2}}, - DownstreamOp3 = {addRight, {ok, 1, 1}, {ok, 2, 3}}, - {ok, L1} = update(DownstreamOp1, L), - {ok, L2} = update(DownstreamOp2, L1), - {ok, L3} = update(DownstreamOp3, L2), - {ok, DownstreamOp4} = generate_downstream({remove, 2}, 1, L3), - {ok, L4} = update(DownstreamOp4, L3), - {ok, L5} = purge_tombstones(L4), - ?assertMatch([{ok, 1, _}, {ok, 3, _}], L5). - -%% This test creates two RGAs and performs updates, checking they reach -%% the same final state after the four updates are aplied in both replicas. -concurrent_updates_in_two_replicas_test() -> - R1_0 = new(), - R2_0 = new(), - {ok, DownstreamOp1} = generate_downstream({addRight, 1, 0}, 1, R1_0), - {ok, DownstreamOp2} = generate_downstream({addRight, 2, 0}, 1, R2_0), - {ok, R1_1} = update(DownstreamOp1, R1_0), - {ok, R2_1} = update(DownstreamOp2, R2_0), - {ok, R1_2} = update(DownstreamOp2, R1_1), - {ok, R2_2} = update(DownstreamOp1, R2_1), - ?assertEqual(R1_2, R2_2), - {ok, DownstreamOp3} = generate_downstream({addRight, 3, 2}, 1, R1_2), - {ok, DownstreamOp4} = generate_downstream({addRight, 4, 2}, 1, R2_2), - {ok, R1_3} = update(DownstreamOp3, R1_2), - {ok, R2_3} = update(DownstreamOp4, R2_2), - {ok, R1_4} = update(DownstreamOp4, R1_3), - {ok, R2_4} = update(DownstreamOp3, R2_3), - ?assertEqual(R1_4, R2_4). - -is_operation_test() -> - %% addRight checks - ?assertEqual(false, is_operation({addRight, value, -1})), - ?assertEqual(true, is_operation({addRight, value, 0})), - ?assertEqual(true, is_operation({addRight, value, 1})), - - %% remove checks - ?assertEqual(false, is_operation({remove, -1})), - ?assertEqual(true, is_operation({remove, 0})), - ?assertEqual(true, is_operation({remove, 1})), - - %% invalid operation checks - ?assertEqual(false, is_operation({anything, 1})), - ?assertEqual(false, is_operation({add, 1, 4})). - --endif. From 7c4cc68a69dc8e198a6901fee1dd3ab1080a8b46 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 12 May 2016 14:30:50 +0200 Subject: [PATCH 108/426] bcounter to antidote_crdt behaviour --- src/antidote_crdt_bcounter.erl | 113 ++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 52 deletions(-) diff --git a/src/antidote_crdt_bcounter.erl b/src/antidote_crdt_bcounter.erl index 56eb1d8eb..684c705fe 100644 --- a/src/antidote_crdt_bcounter.erl +++ b/src/antidote_crdt_bcounter.erl @@ -12,18 +12,28 @@ %% All operations on this CRDT are monotonic and do not keep extra tombstones. %% @end --module(crdt_bcounter). +-module(antidote_crdt_bcounter). + +-behaviour(antidote_crdt). + +-include("antidote_crdt.hrl"). + +%% Call backs +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). %% API --export([new/0, - localPermissions/2, - permissions/1, - value/1, - generate_downstream/3, - update/2, - to_binary/1, - from_binary/1, - is_operation/1]). +-export([localPermissions/2, + permissions/1 + ]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -34,8 +44,8 @@ -opaque bcounter() :: {orddict:orddict(),orddict:orddict()}. -type binary_bcounter() :: binary(). -type bcounter_op() :: bcounter_anon_op() | bcounter_src_op(). --type bcounter_anon_op() :: {transfer, pos_integer(), id()} | - {increment, pos_integer()} | {decrement, pos_integer()}. +-type bcounter_anon_op() :: {transfer, pos_integer(), id(), id()} | + {increment, {pos_integer(), id()}} | {decrement, {pos_integer(), id()}}. -type bcounter_src_op() :: {bcounter_anon_op(), id()}. -opaque id() :: term. %% A replica's identifier. @@ -109,12 +119,12 @@ value(Counter) -> Counter. %% This operation fails and returns `{error, no_permissions}' %% if it tries to consume resources unavailable to the source replica %% (which prevents logging of forbidden attempts). --spec generate_downstream(bcounter_op(), riak_dt:actor(), bcounter()) -> {ok, bcounter_op()} | {error, no_permissions}. -generate_downstream({increment,V}, Actor, _Counter) when is_integer(V), V > 0 -> - {ok, {{increment,V},Actor}}; -generate_downstream({decrement,V}, Actor, Counter) when is_integer(V), V > 0 -> +-spec downstream(bcounter_op(), bcounter()) -> {ok, bcounter_op()} | {error, no_permissions}. +downstream({increment,{V, Actor}}, _Counter) when is_integer(V), V > 0 -> + {ok, {{increment,V}, Actor}}; +downstream({decrement,{V, Actor}}, Counter) when is_integer(V), V > 0 -> generate_downstream_check({decrement,V}, Actor, Counter, V); -generate_downstream({transfer,V,To}, Actor, Counter) when is_integer(V), V > 0 -> +downstream({transfer,{V,To, Actor}}, Counter) when is_integer(V), V > 0 -> generate_downstream_check({transfer,V,To}, Actor, Counter, V). generate_downstream_check(Op, Actor, Counter, V) -> @@ -160,22 +170,21 @@ from_binary(<>) -> binary_to_term(B). -spec is_operation(term()) -> boolean(). is_operation(Operation) -> case Operation of - {decrement, Number} -> - is_integer(Number) andalso (Number >= 0); - {increment, Number} -> + {decrement, {Number, _Actor}} -> is_integer(Number) andalso (Number >= 0); - {transfer, Number, _} -> + {increment, {Number, _Actor}} -> is_integer(Number) andalso (Number >= 0); - {{decrement, Number}, _} -> - is_integer(Number) andalso (Number >= 0); - {{increment, Number}, _} -> - is_integer(Number) andalso (Number >= 0); - {{transfer, Number, _}, _} -> + {transfer, {Number, _, _Actor}} -> is_integer(Number) andalso (Number >= 0); _ -> false end. +require_state_downstream(_) -> + true. + +equal(BCounter1, BCounter2) -> + BCounter1 == BCounter2. %% =================================================================== %% EUnit tests @@ -184,8 +193,8 @@ is_operation(Operation) -> -ifdef(TEST). %% Utility to generate and apply downstream operations. -apply_op(Op, Actor, Counter) -> - {ok, OP_DS} = generate_downstream(Op, Actor, Counter), +apply_op(Op, Counter) -> + {ok, OP_DS} = downstream(Op, Counter), {ok, NewCounter} = update(OP_DS, Counter), NewCounter. @@ -196,8 +205,8 @@ new_test() -> %% Tests increment operations. increment_test() -> Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), - Counter2 = apply_op({increment, 5}, r2, Counter1), + Counter1 = apply_op({increment, {10, r1}}, Counter0), + Counter2 = apply_op({increment, {5, r2}}, Counter1), %% Test replicas' values. ?assertEqual(5, localPermissions(r2,Counter2)), ?assertEqual(10, localPermissions(r1,Counter2)), @@ -207,7 +216,7 @@ increment_test() -> %% Tests the function `localPermissions()'. localPermisisons_test() -> Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter1 = apply_op({increment, {10, r1}}, Counter0), %% Test replica with positive amount of permissions. ?assertEqual(10, localPermissions(r1,Counter1)), %% Test nonexistent replica. @@ -216,45 +225,45 @@ localPermisisons_test() -> %% Tests decrement operations. decrement_test() -> Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter1 = apply_op({increment, {10, r1}}, Counter0), %% Test allowed decrement. - Counter2 = apply_op({decrement, 6}, r1, Counter1), + Counter2 = apply_op({decrement, {6, r1}}, Counter1), ?assertEqual(4, permissions(Counter2)), %% Test nonexistent replica. ?assertEqual(0, localPermissions(r2,Counter1)), %% Test forbidden decrement. - OP_DS = generate_downstream({decrement, 6}, r1, Counter2), + OP_DS = downstream({decrement, {6, r1}}, Counter2), ?assertEqual({error,no_permissions}, OP_DS). %% Tests a more complex chain of increment and decrement operations. decrement_increment_test() -> Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), - Counter2 = apply_op({decrement, 6}, r1, Counter1), - Counter3 = apply_op({increment, 6}, r2, Counter2), + Counter1 = apply_op({increment, {10, r1}}, Counter0), + Counter2 = apply_op({decrement, {6, r1}}, Counter1), + Counter3 = apply_op({increment, {6, r2}}, Counter2), %% Test several replicas (balance each other). ?assertEqual(10, permissions(Counter3)), %% Test forbidden permissions, when total is higher than consumed. - OP_DS = generate_downstream({decrement, 6}, r1, Counter3), + OP_DS = downstream({decrement, {6, r1}}, Counter3), ?assertEqual({error,no_permissions}, OP_DS), %% Test the same operation is allowed on another replica with enough permissions. - Counter4 = apply_op({decrement, 6}, r2, Counter3), + Counter4 = apply_op({decrement, {6, r2}}, Counter3), ?assertEqual(4, permissions(Counter4)). %% Tests transferring permissions. transfer_test() -> Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), + Counter1 = apply_op({increment, {10, r1}}, Counter0), %% Test transferring permissions from one replica to another. - Counter2 = apply_op({transfer, 6, r2}, r1, Counter1), + Counter2 = apply_op({transfer, {6, r2, r1}}, Counter1), ?assertEqual(4, localPermissions(r1,Counter2)), ?assertEqual(6, localPermissions(r2,Counter2)), ?assertEqual(10, permissions(Counter2)), %% Test transference forbidden by lack of previously transfered resources. - OP_DS = generate_downstream({transfer, 5, r2}, r1, Counter2), + OP_DS = downstream({transfer, {5, r2, r1}}, Counter2), ?assertEqual({error,no_permissions}, OP_DS), %% Test transference enabled by previously transfered resources. - Counter3 = apply_op({transfer, 5, r1}, r2, Counter2), + Counter3 = apply_op({transfer, {5, r1, r2}}, Counter2), ?assertEqual(9, localPermissions(r1,Counter3)), ?assertEqual(1, localPermissions(r2,Counter3)), ?assertEqual(10, permissions(Counter3)). @@ -263,9 +272,9 @@ transfer_test() -> value_test() -> %% Test on `bcounter()' resulting from applying all kinds of operation. Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), - Counter2 = apply_op({decrement, 6}, r1, Counter1), - Counter3 = apply_op({transfer, 2, r2}, r1, Counter2), + Counter1 = apply_op({increment, {10, r1}}, Counter0), + Counter2 = apply_op({decrement, {6, r1}}, Counter1), + Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), %% Assert `value()' returns `bcounter()' itself. ?assertEqual(Counter3, value(Counter3)). @@ -273,18 +282,18 @@ value_test() -> binary_test() -> %% Test on `bcounter()' resulting from applying all kinds of operation. Counter0 = new(), - Counter1 = apply_op({increment, 10}, r1, Counter0), - Counter2 = apply_op({decrement, 6}, r1, Counter1), - Counter3 = apply_op({transfer, 2, r2}, r1, Counter2), + Counter1 = apply_op({increment, {10, r1}}, Counter0), + Counter2 = apply_op({decrement, {6, r1}}, Counter1), + Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), %% Assert marshaling and unmarshaling holds the same `bcounter()'. B = to_binary(Counter3), ?assertEqual(Counter3, from_binary(B)). is_operation_test() -> - ?assertEqual(true, is_operation({transfer, 2, r2})), - ?assertEqual(true, is_operation({increment, 50})), + ?assertEqual(true, is_operation({transfer, {2, r2, r1}})), + ?assertEqual(true, is_operation({increment, {50, r1}})), ?assertEqual(false, is_operation(increment)), - ?assertEqual(true, is_operation({decrement, 50})), + ?assertEqual(true, is_operation({decrement, {50, r1}})), ?assertEqual(false, is_operation(decrement)), ?assertEqual(false, is_operation({anything, [1,2,3]})). From cccc590cdda3274b22ea77c42c6de6f290f75c3a Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 12 May 2016 15:05:02 +0200 Subject: [PATCH 109/426] antidote_gset using riak_dt --- src/antidote_crdt_gset.erl | 86 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/antidote_crdt_gset.erl diff --git a/src/antidote_crdt_gset.erl b/src/antidote_crdt_gset.erl new file mode 100644 index 000000000..51194ac21 --- /dev/null +++ b/src/antidote_crdt_gset.erl @@ -0,0 +1,86 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc module antidote_crdt_gset - A wrapper around riak_dt_gset + +-module(antidote_crdt_gset). + +-behaviour(antidote_crdt). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-define(RIAK_MODULE, riak_dt_gset). + +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +-type gset() :: riak_dt_gset:gset(). +-type gset_op() :: {add, {member(), actor()}} | {remove, {member(), actor()}} | + {add_all, {[member()], actor()}} | {remove_all, {[member()], actor()}}. + +-type member() :: term(). +-type actor() :: riak_dt:actor(). + +new() -> + ?RIAK_MODULE:new(). + +value(Set) -> + ?RIAK_MODULE:value(Set). + +-spec downstream(gset_op(), gset()) -> {ok, term()}. +downstream({Op, {OpParam, Actor}}, State) -> + {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), + {ok, {merge, S0}}. + +update({merge, State1}, State2) -> + {ok, ?RIAK_MODULE:merge(State1, State2)}. + +require_state_downstream(_Operation) -> true. + +is_operation(Operation) -> + ?RIAK_MODULE:is_operation(Operation). + +equal(CRDT1, CRDT2) -> + ?RIAK_MODULE:equal(CRDT1,CRDT2). + +to_binary(CRDT) -> + ?RIAK_MODULE:to_binary(CRDT). + +from_binary(Bin) -> + ?RIAK_MODULE:from_binary(Bin). + +-ifdef(test). +all_test() -> + S0 = new(), + {ok, Downstream} = downstream({add, {a, actor}}, S0), + {ok, S1} = update(Downstream, S0), + ?assertEqual(1, riak_dt_gset:stat(element_count, S1)). + +-endif. From cf5b96310b756e0e03f8a2294ca9c775b75104dc Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 12 May 2016 16:41:26 +0200 Subject: [PATCH 110/426] fix operation format --- src/antidote_crdt_rga.erl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/antidote_crdt_rga.erl b/src/antidote_crdt_rga.erl index 67f83278c..aee9c9a5f 100644 --- a/src/antidote_crdt_rga.erl +++ b/src/antidote_crdt_rga.erl @@ -77,7 +77,7 @@ new() -> %% If the operation is addRight, generates a unique token for the new element. %% If the operation is remove, fetches the vertex of the element to be removed. -spec downstream(rga_op(), rga()) -> {ok, rga_downstream_op()} | {error, {invalid_position, number()}}. -downstream({addRight, Elem, Position}, Rga) -> +downstream({addRight, {Elem, Position}}, Rga) -> case (Position < 0) or (Position > length(Rga)) of true -> {error, {invalid_position, Position}}; false -> case (Rga == []) or (Position == 0) of @@ -145,7 +145,7 @@ unique() -> %% @doc The following operation verifies that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). -is_operation({addRight, _, Position}) -> +is_operation({addRight, {_, Position}}) -> (is_integer(Position) and (Position >= 0)); is_operation({remove, Position})-> (is_integer(Position) and (Position >= 0)); @@ -171,34 +171,34 @@ new_test() -> generate_downstream_invalid_position_test() -> L = new(), - Result1 = downstream({addRight, 1, 1}, L), + Result1 = downstream({addRight, {1, 1}}, L), ?assertMatch({error, {invalid_position, 1}}, Result1), - Result2 = downstream({addRight, 1, -1}, L), + Result2 = downstream({addRight, {1, -1}}, L), ?assertMatch({error, {invalid_position, -1}}, Result2). generate_downstream_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = downstream({addRight, 4, 0}, L), + {ok, DownstreamOp} = downstream({addRight, {4, 0}}, L), ?assertMatch({addRight, {ok, 0, 0}, {ok, 4, _}}, DownstreamOp). generate_downstream_non_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = downstream({addRight, 4, 0}, L), + {ok, DownstreamOp} = downstream({addRight, {4, 0}}, L), {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = downstream({addRight, 3, 1}, L1), + {ok, DownstreamOp1} = downstream({addRight, {3, 1}}, L1), ?assertMatch({addRight, {ok, 4, _}, {ok, 3, _}}, DownstreamOp1). add_right_in_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = downstream({addRight, 1, 0}, L), + {ok, DownstreamOp} = downstream({addRight, {1, 0}}, L), {ok, L1} = update(DownstreamOp, L), ?assertMatch([{ok, 1, _}], L1). add_right_in_non_empty_rga_test() -> L = new(), - {ok, DownstreamOp} = downstream({addRight, 1, 0}, L), + {ok, DownstreamOp} = downstream({addRight, {1, 0}}, L), {ok, L1} = update(DownstreamOp, L), - {ok, DownstreamOp1} = downstream({addRight, 2, 1}, L1), + {ok, DownstreamOp1} = downstream({addRight, {2, 1}}, L1), {ok, L2} = update(DownstreamOp1, L1), ?assertMatch([{ok, 1, _}, {ok, 2, _}], L2). @@ -283,15 +283,15 @@ purge_tombstones_test() -> concurrent_updates_in_two_replicas_test() -> R1_0 = new(), R2_0 = new(), - {ok, DownstreamOp1} = downstream({addRight, 1, 0}, R1_0), - {ok, DownstreamOp2} = downstream({addRight, 2, 0}, R2_0), + {ok, DownstreamOp1} = downstream({addRight, {1, 0}}, R1_0), + {ok, DownstreamOp2} = downstream({addRight, {2, 0}}, R2_0), {ok, R1_1} = update(DownstreamOp1, R1_0), {ok, R2_1} = update(DownstreamOp2, R2_0), {ok, R1_2} = update(DownstreamOp2, R1_1), {ok, R2_2} = update(DownstreamOp1, R2_1), ?assertEqual(R1_2, R2_2), - {ok, DownstreamOp3} = downstream({addRight, 3, 2}, R1_2), - {ok, DownstreamOp4} = downstream({addRight, 4, 2}, R2_2), + {ok, DownstreamOp3} = downstream({addRight, {3, 2}}, R1_2), + {ok, DownstreamOp4} = downstream({addRight, {4, 2}}, R2_2), {ok, R1_3} = update(DownstreamOp3, R1_2), {ok, R2_3} = update(DownstreamOp4, R2_2), {ok, R1_4} = update(DownstreamOp4, R1_3), @@ -300,9 +300,9 @@ concurrent_updates_in_two_replicas_test() -> is_operation_test() -> %% addRight checks - ?assertEqual(false, is_operation({addRight, value, -1})), - ?assertEqual(true, is_operation({addRight, value, 0})), - ?assertEqual(true, is_operation({addRight, value, 1})), + ?assertEqual(false, is_operation({addRight, {value, -1}})), + ?assertEqual(true, is_operation({addRight, {value, 0}})), + ?assertEqual(true, is_operation({addRight, {value, 1}})), %% remove checks ?assertEqual(false, is_operation({remove, -1})), From 0d7ec171a38cd00f90b192d3fa6a1e9ede229c0e Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 09:40:11 +0200 Subject: [PATCH 111/426] fix type spec --- src/antidote_crdt_rga.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidote_crdt_rga.erl b/src/antidote_crdt_rga.erl index aee9c9a5f..14186f2d4 100644 --- a/src/antidote_crdt_rga.erl +++ b/src/antidote_crdt_rga.erl @@ -63,7 +63,7 @@ -type rga_downstream_op() :: {addRight, vertex(), vertex()} | {remove, {ok, any(), number()}}. --type rga_op() :: {addRight, any(), non_neg_integer()} | {remove, non_neg_integer()}. +-type rga_op() :: {addRight, {any(), non_neg_integer()}} | {remove, non_neg_integer()}. -type rga_result() :: {ok, rga()}. From 26040d2ecfc964aa6f8c6ac8f01ea1204bc578a8 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 10:13:30 +0200 Subject: [PATCH 112/426] supported types --- include/antidote_crdt.hrl | 5 ++--- src/antidote_crdt.erl | 13 +++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/antidote_crdt.hrl b/include/antidote_crdt.hrl index 15ffe5ad3..daece3437 100644 --- a/include/antidote_crdt.hrl +++ b/include/antidote_crdt.hrl @@ -1,12 +1,11 @@ -type crdt() :: term(). --type update() :: term(). +-type update() :: {atom(), term()}. -type effect() :: term(). -type value() :: term(). -type reason() :: term(). -type pncounter() :: integer(). --type pncounter_update() :: increment | decrement | - {increment, integer()} | +-type pncounter_update() :: {increment, integer()} | {decrement, integer()}. -type pncounter_effect() :: pncounter_update(). -type pncounter_value() :: integer(). diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index c1e77581b..50742e717 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -25,6 +25,16 @@ -include("antidote_crdt.hrl"). +-define(CRDTS, [antidote_crdt_counter, + antidote_crdt_orset, + antidote_crdt_gset, + antidote_crdt_rga, + antidote_crdt_bcounter + ]). + +-export([is_type/1 + ]). + -callback new() -> crdt(). -callback value(crdt()) -> value(). -callback downstream(update(), crdt()) -> {ok, effect()} | {error, reason()}. @@ -41,4 +51,7 @@ %-callback stats(crdt()) -> [{atom(), number()}]. %-callback stat(atom(), crdt()) -> number() | undefined. +is_type(Type) -> + is_atom(Type) andalso lists:member(Type, ?CRDTS). + %% End of Module. From 2fd77f0161e897d33b8757ff667017ba806f5e4f Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 10:33:33 +0200 Subject: [PATCH 113/426] fix type specs --- src/antidote_crdt_bcounter.erl | 10 +++++----- src/antidote_crdt_counter.erl | 2 -- src/antidote_crdt_orset.erl | 4 +--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/antidote_crdt_bcounter.erl b/src/antidote_crdt_bcounter.erl index 684c705fe..f154042eb 100644 --- a/src/antidote_crdt_bcounter.erl +++ b/src/antidote_crdt_bcounter.erl @@ -44,7 +44,7 @@ -opaque bcounter() :: {orddict:orddict(),orddict:orddict()}. -type binary_bcounter() :: binary(). -type bcounter_op() :: bcounter_anon_op() | bcounter_src_op(). --type bcounter_anon_op() :: {transfer, pos_integer(), id(), id()} | +-type bcounter_anon_op() :: {transfer, {pos_integer(), id(), id()}} | {increment, {pos_integer(), id()}} | {decrement, {pos_integer(), id()}}. -type bcounter_src_op() :: {bcounter_anon_op(), id()}. -opaque id() :: term. %% A replica's identifier. @@ -119,7 +119,7 @@ value(Counter) -> Counter. %% This operation fails and returns `{error, no_permissions}' %% if it tries to consume resources unavailable to the source replica %% (which prevents logging of forbidden attempts). --spec downstream(bcounter_op(), bcounter()) -> {ok, bcounter_op()} | {error, no_permissions}. +-spec downstream(bcounter_op(), bcounter()) -> {ok, term()} | {error, no_permissions}. downstream({increment,{V, Actor}}, _Counter) when is_integer(V), V > 0 -> {ok, {{increment,V}, Actor}}; downstream({decrement,{V, Actor}}, Counter) when is_integer(V), V > 0 -> @@ -137,7 +137,7 @@ generate_downstream_check(Op, Actor, Counter, V) -> %% usually created with `generate_downstream'. %% %% Return the resulting `bcounter()' after applying the operation. --spec update(bcounter_op(), bcounter()) -> {ok, bcounter()}. +-spec update(term(), bcounter()) -> {ok, bcounter()}. update({{increment, V},Id}, Counter) -> increment(Id,V,Counter); update({{decrement, V},Id}, Counter) -> @@ -162,8 +162,8 @@ transfer(From,To,V,{P,D}) -> to_binary(C) -> term_to_binary(C). %% doc Return a `bcounter()' from its binary representation. --spec from_binary(binary()) -> bcounter(). -from_binary(<>) -> binary_to_term(B). +-spec from_binary(binary()) -> {ok, bcounter()}. +from_binary(<>) -> {ok, binary_to_term(B)}. %% @doc The following operation verifies %% that Operation is supported by this particular CRDT. diff --git a/src/antidote_crdt_counter.erl b/src/antidote_crdt_counter.erl index d2ce6d49f..3014106d8 100644 --- a/src/antidote_crdt_counter.erl +++ b/src/antidote_crdt_counter.erl @@ -44,7 +44,6 @@ ]). %% @doc Create a new, empty 'pncounter()' --spec new() -> pncounter(). new() -> 0. @@ -119,7 +118,6 @@ is_operation(_) -> false. %% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt %% to generate downstream effect --spec require_state_downstream(update()) -> boolean(). require_state_downstream(_) -> false. diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index f92dfebc3..ab0d8da1d 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -142,8 +142,7 @@ downstream({remove_all,Elems}, ORDict) -> %% For update, the second element of the tuple is a list of updates to apply, each of which can %% either be add, add_all or remove, remove_all. -spec update(orset_op(), orset()) -> - {ok, orset()} | - {error, {precondition ,{not_present, member()}}}. + {ok, orset()}. update({add, {Elem, [Token|_]}}, ORDict) -> add_elem(Elem,Token,ORDict); update({add_all,Elems}, ORDict0) -> @@ -253,7 +252,6 @@ minimum_tokens(Tokens) -> %% @doc The following operation verifies %% that Operation is supported by this particular CRDT. --spec is_operation(term()) -> boolean(). is_operation({add, _Elem}) -> true; is_operation({add_all, [_H|_T]}) -> true; is_operation({remove, _Elem}) -> From 80eeb8b5085c3d67a145830d8cab1ccada696aa1 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 10:49:55 +0200 Subject: [PATCH 114/426] add makefile --- Makefile | 26 ++++++++++++++++++++++++++ tools.mk | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 Makefile create mode 100644 tools.mk diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..142ec4d57 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +.PHONY: rel deps test + +all: deps compile + +compile: deps + @./rebar compile + +app: + @./rebar compile skip_deps=true + +deps: + @./rebar get-deps + +clean: + @./rebar clean + +distclean: clean + @./rebar delete-deps + +DIALYZER_APPS = kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \ + xmerl webtool eunit syntax_tools compiler mnesia public_key snmp + +include tools.mk + +typer: + typer --annotate -I ../ --plt $(PLT) -r src diff --git a/tools.mk b/tools.mk new file mode 100644 index 000000000..66c6a16c5 --- /dev/null +++ b/tools.mk @@ -0,0 +1,57 @@ +REBAR ?= ./rebar + +test: compile + ${REBAR} eunit skip_deps=true + +docs: + ${REBAR} doc skip_deps=true + +xref: compile + ${REBAR} xref skip_deps=true + +PLT ?= $(HOME)/.combo_dialyzer_plt +LOCAL_PLT = .local_dialyzer_plt +DIALYZER_FLAGS ?= -Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspecs + +${PLT}: compile + @if [ -f $(PLT) ]; then \ + dialyzer --check_plt --plt $(PLT) --apps $(DIALYZER_APPS) && \ + dialyzer --add_to_plt --plt $(PLT) --output_plt $(PLT) --apps $(DIALYZER_APPS) ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(PLT) --apps $(DIALYZER_APPS); test $$? -ne 1; \ + fi + +${LOCAL_PLT}: compile + @if [ -d deps ]; then \ + if [ -f $(LOCAL_PLT) ]; then \ + dialyzer --check_plt --plt $(LOCAL_PLT) deps/*/ebin && \ + dialyzer --add_to_plt --plt $(LOCAL_PLT) --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + fi \ + fi + +dialyzer: ${PLT} ${LOCAL_PLT} + @echo "==> $(shell basename $(shell pwd)) (dialyzer)" + @if [ -f $(LOCAL_PLT) ]; then \ + PLTS="$(PLT) $(LOCAL_PLT)"; \ + else \ + PLTS=$(PLT); \ + fi; \ + if [ -f dialyzer.ignore-warnings ]; then \ + if [ $$(grep -cvE '[^[:space:]]' dialyzer.ignore-warnings) -ne 0 ]; then \ + echo "ERROR: dialyzer.ignore-warnings contains a blank/empty line, this will match all messages!"; \ + exit 1; \ + fi; \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin > dialyzer_warnings ; \ + egrep -v "^[[:space:]]*(done|Checking|Proceeding|Compiling)" dialyzer_warnings | grep -F -f dialyzer.ignore-warnings -v > dialyzer_unhandled_warnings ; \ + cat dialyzer_unhandled_warnings ; \ + [ $$(cat dialyzer_unhandled_warnings | wc -l) -eq 0 ] ; \ + else \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin; \ + fi + +cleanplt: + rm -f $(PLT) + rm -f $(LOCAL_PLT) + From 53325a3f43335c588c2a236aacec6455cbce8626 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 11:36:27 +0200 Subject: [PATCH 115/426] fix test --- src/antidote_crdt_bcounter.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidote_crdt_bcounter.erl b/src/antidote_crdt_bcounter.erl index f154042eb..c6b351559 100644 --- a/src/antidote_crdt_bcounter.erl +++ b/src/antidote_crdt_bcounter.erl @@ -287,7 +287,7 @@ binary_test() -> Counter3 = apply_op({transfer, {2, r2, r1}}, Counter2), %% Assert marshaling and unmarshaling holds the same `bcounter()'. B = to_binary(Counter3), - ?assertEqual(Counter3, from_binary(B)). + ?assertEqual({ok, Counter3}, from_binary(B)). is_operation_test() -> ?assertEqual(true, is_operation({transfer, {2, r2, r1}})), From 68de23af917a8e716864703bf9fc8a06b2c6303b Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 11:37:03 +0200 Subject: [PATCH 116/426] add mvreg implementation from antidote --- src/antidote_crdt_mvreg.erl | 507 ++++++++++++++++++++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 src/antidote_crdt_mvreg.erl diff --git a/src/antidote_crdt_mvreg.erl b/src/antidote_crdt_mvreg.erl new file mode 100644 index 000000000..d070c9a89 --- /dev/null +++ b/src/antidote_crdt_mvreg.erl @@ -0,0 +1,507 @@ +%% ------------------------------------------------------------------- +%% +%% riak_dt_mvreg: A DVVSet based multi value register +%% +%% Copyright (c) 2007-2013 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc +%% A Multi-Value Register CRDT. +%% There are two kinds of updates: assign and propagate. Assign is use for a +%% single replica of MVReg where updates are linealizable. Propagate is used +%% to propagate update from a replica to other replicas. It is similar to the +%% 'merge' operation of the state-based specifiction of MVReg. +%% +%% This file is adapted from riak_dt_lwwreg, a state-based implementation of +%% last-writer-wins register. +%% The changes are as follows: +%% 1. The return value of an MVReg is a list of {value, vclock} pairs, as MVReg +%% may contain multiple values. +%% 2. There is a new kind of operation: propagate, which stands for merging the +%% contents of two MVRegs. +%% +%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of +%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ +%% +%% @end + +-module(antidote_crdt_mvreg). + +-behaviour(antidote_crdt). + +%% Callbacks +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +-export([parent_clock/2, + value/2, + init/2, + stats/1, + to_binary/2, + to_version/2 + ]). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-export_type([mvreg/0, mvreg_op/0]). + +%% TODO: make opaque +-type actor() :: term(). +-type ts() :: non_neg_integer(). +-type mvreg() :: [{term(), riak_dt_vclock:vclock()}]. + +-type mvreg_op() :: {assign, {term(), ts()}} + | {assign, term()} + | {propagate, {term(), ts()}}. + +-type mv_q() :: timestamp. + +%% @doc Create a new, empty `mvreg()' +-spec new() -> mvreg(). +new() -> + [{<<>>, riak_dt_vclock:fresh()}]. + +-spec init(term(), riak_dt_vclock:vclock()) -> mvreg(). +init(Value, VC) -> + [{Value, VC}]. + +-spec parent_clock(riak_dt_vclock:vclock(), mvreg()) -> mvreg(). +parent_clock(_Clock, Reg) -> + Reg. + +%% @doc The values of this `mvreg()'. Multiple values can be returned, +%% since there can be diverged value in this register. +-spec value(mvreg()) -> [term()]. +value(MVReg) -> + [Val || {Val, _VC} <- MVReg]. + +%% @doc query for this `mvreg()' of its timestamp. +%% `timestamp' is the only query option. +-spec value(mv_q(), mvreg()) -> [riak_dt_vclock:vclock()]. +value(timestamp, MVReg) -> + [VC || {_Val, VC} <- MVReg]. + +%% @doc Assign `Value' to this register. The vector clock of this +%% register will be incremented by one for the corresponding `Actor'. +%% In case the register has multiple diverged values, firstly a vector +%% clock that dominates all of them is calculated, then incrementation +%% for `Actor' is applied. +%% +%% This kind of update is supposed to be linealizable so the operation +%% issuer does not need to provide the vector clock it has observed. +-spec downstream(mvreg_op(), mvreg()) -> {ok, term()}. +downstream({assign, {Value, Actor}}, MVReg) -> + VV = inc_vv(MVReg, Actor), + NewMVReg = [{Value, VV}], + {ok, {merge, NewMVReg}}; + +%% @doc Assign a `Value' to the `mvreg()' associating the update with +%% time `TS', if `TS' is larger than the current timestamp for `Actor'. +downstream({assign, {Value, TS, Actor}}, MVReg) -> + case larger_than(TS, Actor, MVReg) of + true -> + VV = inc_vv(MVReg, Actor), + NewMVReg = init(Value, VV), + downstream({assign, {Value, TS, Actor}}, NewMVReg); + false -> + {ok, {merge, MVReg}} + end; + +%% @doc Propagate the `Value' of a `mvreg()' to other replicas. The +%% `Value' and its vector clock `TS' is the parameter. It is assumed +%% that propagation only happens after one update is applied, therefore +%% `Value' is a single term and `TS' can only be one vector clock. All +%% compatible vector clocks (being descendent of another) will be +%% merged; non-compatible vector clocks will be kept in a list. +%% Corresponding values of non-compatible vector clocks will also be +%% kept. +downstream({propagate, {Value, TS, _Actor}}, MVReg ) -> + {ok, {merge, merge(MVReg, init(Value, TS))}}. + +update({merge, MVreg1}, MVreg2) -> + {ok, merge(MVreg1, MVreg2)}. + +%% @doc Find a least-uppder bound for all non-compatible vector clocks +%% in MVReg (if there is any) and then increment timestamp for `Actor' +%% by one. +-spec inc_vv(mvreg(), actor()) -> riak_dt_vclock:vclock(). +inc_vv(MVReg, Actor) -> + VCL = [VC || {_Val, VC} <- MVReg], + [H|T] = VCL, + MaxVC = lists:foldl(fun(VC, Acc) -> riak_dt_vclock:merge([VC, Acc]) end, H, T), + NewVC = riak_dt_vclock:increment(Actor, MaxVC), + NewVC. + +%% @doc If `TS'(timestamp) is larger than all entries of `Actor' for the +%% MVReg. +-spec larger_than(ts(), actor(), mvreg()) -> boolean(). +larger_than(_TS, _Actor, []) -> + true; +larger_than(TS, Actor, [H|T]) -> + {_Value, VC} = H, + OldTS = riak_dt_vclock:get_counter(Actor, VC), + case TS > OldTS of + true -> + larger_than(TS, Actor, T); + false -> + false + end. + +%% @doc If any timestamp in the first list descends the second vector clock. +-spec if_descends([riak_dt_vclock:vclock()], riak_dt_vclock:vclock()) -> boolean(). +if_descends([], _VC) -> + false; +if_descends([H|T], VC) -> + case riak_dt_vclock:descends(H, VC) of + true -> + true; + false -> + if_descends(T, VC) + end. + + +%% @doc Merge two `mvreg()'s to a single `mvreg()'. This is the Least Upper Bound +%% function described in the literature. +-spec merge(mvreg(), mvreg()) -> mvreg(). +merge(MVReg1, MVReg2) -> + merge(MVReg1, MVReg2, []). + +%% @doc Helper function of `merge/2'. It removes value entries that are descendes of +%% any other. Remainder are value entries whose vector clock is neither descendent of +%% any other entry nor being ascendent of any other. +merge([], MVReg2, Remainder) -> + MVReg2++Remainder; +merge(MVReg1, [], Remainder) -> + MVReg1++Remainder; +merge(MVReg1, MVReg2, Remainder) -> + {_, HVC} = hd(MVReg2), + case if_descends(value(timestamp, MVReg1), HVC) of + true -> + merge(MVReg1, tl(MVReg2), Remainder); + false -> + NewMVReg1 = lists:filter(fun({_, ElemVC}) -> riak_dt_vclock:descends(HVC, ElemVC) == false end, MVReg1), + merge(NewMVReg1, tl(MVReg2), Remainder++[hd(MVReg2)]) + end. + +%% @doc Are two `mvreg()'s structurally equal? This is not `value/1' equality. +%% Two registers might represent the value `armchair', and not be `equal/2'. Equality here is +%% that both registers contain the same value and timestamp. +-spec equal(mvreg(), mvreg()) -> boolean(). +equal(MVReg1, MVReg2) -> + eq(lists:sort(MVReg1), lists:sort(MVReg2)). + +%% @doc Helper function for `equal/2'. It receives two sorted `mvreg()' as parameters and can do +%% comparison directly without concerning about disorder. This is difficult to handle direclty by +%% `equal/2' without adding extra parameter, thus `eq/2' is used. +eq([], []) -> + true; +eq([H1|T1], [H2|T2]) -> + {V1, TS1} = H1, + {V2, TS2} = H2, + VEqual = V1 =:= V2, + TSEqual = riak_dt_vclock:equal(TS1, TS2), + case VEqual andalso TSEqual of + true -> + eq(T1, T2); + false -> + false + end; +eq(_, _) -> + false. + +%% @doc Return statistics of an `mvreg()'. Currently only `value_size' is returned. +-spec stats(mvreg()) -> [{atom(), non_neg_integer()}]. +stats(MVReg) -> + [{value_size, stat(value_size, MVReg)}]. + +-spec stat(atom(), mvreg()) -> non_neg_integer() | undefined. +stat(value_size, MVReg) -> + Values = value(MVReg), + TS = value(timestamp, MVReg), + Size = erlang:external_size(Values) + erlang:external_size(TS), + Size; +stat(_, _) -> undefined. + +-include_lib("riak_dt/include/riak_dt_tags.hrl"). +-define(DT_MVREG_TAG, 85). +-define(TAG, ?DT_MVREG_TAG). +-define(V1_VERS, 1). + +%% @doc Encode an effecient binary representation of an `mvreg()' +%% Not working yet... +-spec to_binary(mvreg()) -> binary(). +to_binary(MVReg) -> + <>. + +%% @doc Decode binary `mvreg()' +-spec from_binary(binary()) -> {ok, mvreg()} | {error, ?UNSUPPORTED_VERSION} | ?INVALID_BINARY. +from_binary(<>) -> + {ok, riak_dt:from_binary(Bin)}; +from_binary(<>) -> + {error, ?UNSUPPORTED_VERSION(Vers)}; +from_binary(_B) -> + ?INVALID_BINARY. + +%% @doc The following operation verifies +%% that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation(Operation) -> + case Operation of + {assign, {_, _Actor}} -> + true; + {assign, {_, Number, _Actor}} -> + (is_integer(Number) andalso (Number >= 0)); + {propagate, {_, _, _Actor}} -> + true; + _ -> + false + end. + +require_state_downstream(_) -> + true. + +-spec to_binary(Vers :: pos_integer(), mvreg()) -> {ok, binary()} | +?UNSUPPORTED_VERSION. +to_binary(1, MVR) -> + {ok, to_binary(MVR)}; +to_binary(Vers, _MVR) -> + ?UNSUPPORTED_VERSION(Vers). + +-spec to_version(pos_integer(), mvreg()) -> mvreg(). +to_version(_Version, MVR) -> + MVR. + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). + +init_state() -> + [{<<>>, []}]. + +%% @doc Check if `new()' returns an empty string and an empty vector +%% clock. +new_test() -> + ?assertEqual(init_state(), new()). + +%% @doc Check if `value/1' properly returns a list of value or a list of +%% timestamp of MVReg. Checks for an empty register, a register with +%% two values and a register with only one value. +value_test() -> + Val1 = "the rain in spain falls mainly on the plane", + Val2 = "there is no rain", + VC0 = riak_dt_vclock:fresh(), + VC1 = riak_dt_vclock:increment(actor1, VC0), + VC2 = riak_dt_vclock:increment(actor2, VC0), + MVReg0 = new(), + MVReg1 = [{Val1, VC1}, {Val2, VC2}], + MVReg2 = [{Val1, VC1}], + ?assertEqual([<<>>], value(MVReg0)), + ?assertEqual(lists:sort([Val1, Val2]), lists:sort(value(MVReg1))), + ?assertEqual(lists:sort([VC1, VC2]), lists:sort(value(timestamp, MVReg1))), + ?assertEqual([Val1], value(MVReg2)), + ?assertEqual([VC1], value(timestamp, MVReg2)). + +%% @doc Check if `equal/2' works. +equal_test() -> + %% Test equal for empty MVReg + ?assert(equal(init_state(), new())), + MVReg1 = [{value1, [{actor1, 2}, {actor2, 1}]}, {value2, [{actor4, 1}, {actor3, 2}]}], + MVReg2 = [{value2, [{actor4, 1}, {actor3, 2}]}, {value1, [{actor2, 1}, {actor1, 2}]}], + %%Test if different order does not matter. + ?assert(equal(MVReg1, MVReg2)), + MVReg3 = [{value1, [{actor1, 2}, {actor2, 1}]}], + %% MVReg1 is superset of MVReg3 + ?assertNot(equal(MVReg1, MVReg3)), + MVReg4 = [{value1, [{actor1, 2}, {actor2, 1}]}, {value2, [{actor4, 1}, {actor3, 2}]}, {value3, [{actor5, 2}]}], + %% MVReg1 is subset of MVReg4 + ?assertNot(equal(MVReg1, MVReg4)), + MVReg5 = [{value0, [{actor1, 1}, {actor2, 1}]}, {value2, [{actor4, 1}, {actor3, 2}]}], + %% MVReg5 has a value different from MVReg1 + ?assertNot(equal(MVReg1, MVReg5)). + +% @doc Check if `merge/2' works. +merge_test() -> + MVReg1 = [{value1, [{actor1, 2}, {actor2, 1}]}, {value2, [{actor3, 2}, {actor4, 1}]}], + MVReg2 = [{value2, [{actor3, 2}, {actor4, 1}]}, {value1, [{actor1, 2}, {actor2, 1}]}], + MergedMVReg1 = merge(MVReg1, MVReg2), + %% Merge two MVRegs that are same should not change anything + ?assert(equal(MVReg1, MergedMVReg1)), + MVReg3 = [{value1, [{actor1, 2}, {actor2, 1}]}], + MVReg4 = [{value2, [{actor3, 2}, {actor4, 1}]}], + MergedMVReg2 = merge(MVReg3, MVReg4), + %% Merge two disjoint MVRegs should work + ?assert(equal(MVReg1, MergedMVReg2)), + MVReg5 = [{value1, [{actor1, 3}, {actor2, 1}]}, {value2, [{actor1, 2}, {actor2, 3}]}], + MVReg6 = [{value3, [{actor1, 1}, {actor2, 3}]}, {value4, [{actor1, 3}, {actor2, 2}]}], + MergedMVReg3 = merge(MVReg5, MVReg6), + %% Merge two MVRegs that have overlapping + ?assert(equal([{value2, [{actor1, 2}, {actor2, 3}]}, {value4, [{actor1, 3}, {actor2, 2}]}], MergedMVReg3)), + MVReg7 = [{value3, [{actor1, 3}, {actor2, 3}]}], + MergedMVReg4 = merge(MVReg5, MVReg7), + %% Merge two MVRegs that one dominates the other + ?assert(equal(MVReg7, MergedMVReg4)). + + +% @doc Check if `if_dominate/2' works. +if_descends_test() -> + VC1 = [[{actor1, 2}, {actor2, 3}, {actor3,2}], [{actor1,3}, {actor2,1}, {actor4,2}]], + VC2 = [{actor1, 1}], + ?assert(if_descends(VC1, VC2)), + VC3 = [{actor1, 2}, {actor3,1}], + ?assert(if_descends(VC1, VC3)), + VC4 = [{actor3, 1}, {actor4,1}], + ?assertNot(if_descends(VC1, VC4)). + +apply_update(Op, MVreg) -> + {ok, Downstream} = downstream(Op, MVreg), + update(Downstream, MVreg). + +% @doc Check if `update/3' by assign without providing timestamp works. +basic_assign_test() -> + MVReg0 = new(), + VC0 = riak_dt_vclock:fresh(), + VC1 = riak_dt_vclock:increment(actor0, VC0), + VC2 = riak_dt_vclock:increment(actor0, VC1), + {ok, MVReg1} = apply_update({assign, {value0, actor0}}, MVReg0), + ?assertEqual([{value0, VC1}], MVReg1), + {ok, MVReg2} = apply_update({assign, {value1, actor0}}, MVReg1), + ?assertEqual([{value1, VC2}], MVReg2). + +%% @doc Check if `update/3' by assign with timestamp works. +update_assign_withts_test() -> + MVReg0 = new(), + VC0 = riak_dt_vclock:fresh(), + VC1 = riak_dt_vclock:increment(actor1, VC0), + VC2 = riak_dt_vclock:increment(actor1, VC1), + VC3 = riak_dt_vclock:increment(actor1, VC2), + VC4 = riak_dt_vclock:increment(actor1, VC3), + VC5 = riak_dt_vclock:increment(actor2, VC4), + VC6 = riak_dt_vclock:increment(actor2, VC5), + %% Update a MVReg with a large timestamp. The timestmap of MVReg will be updated to given value. + {ok, MVReg1} = apply_update({assign, {value1, 2, actor1}}, MVReg0), + ?assertEqual([{value1, VC2}], MVReg1), + %% Update a MVReg with a lower timestamp than the current one; should have no effect. + {ok, MVReg2} = apply_update({assign, {value0, 1, actor1}}, MVReg1), + ?assertEqual([{value1, VC2}], MVReg2), + %% Test again with higher timestamp for actor1 + {ok, MVReg3} = apply_update({assign, {value2, 4, actor1}}, MVReg2), + ?assertEqual([{value2, VC4}], MVReg3), + %% Test with actor2 + {ok, MVReg4} = apply_update({assign, {value3, 2, actor2}}, MVReg3), + ?assertEqual([{value3, VC6}], MVReg4). + +%% @doc Update a MVReg with two different actors. Check if both actors are kept in the vector clock. +update_diff_actor_test() -> + MVR0 = new(), + VC0 = riak_dt_vclock:fresh(), + VC1 = riak_dt_vclock:increment(actor1, VC0), + VC2 = riak_dt_vclock:increment(actor2, VC1), + {ok, MVR1} = apply_update({assign, {value1, actor1}}, MVR0), + {ok, MVR2} = apply_update({assign, {value2, actor2}}, MVR1), + Value = value(MVR2), + TS = value(timestamp, MVR2), + ?assertEqual([value2], Value), + ?assertEqual([VC2], TS). + +%% @doc Check if `update/3' with propagate works. +propagate_test() -> + MVReg1_0 = new(), + VC0 = riak_dt_vclock:fresh(), + VC1 = riak_dt_vclock:increment(actor1, VC0), + VC2 = riak_dt_vclock:increment(actor2, VC0), + {ok, MVReg1_1} = apply_update({assign, {value1, actor1}}, MVReg1_0), + %% Propagate a timestamp that is not compatible with the current ones + {ok, MVRMerge1} = apply_update({propagate, {value2, VC2, nothing}}, MVReg1_1), + ?assertEqual(lists:sort([value1, value2]), lists:sort(value(MVRMerge1))), + ?assertEqual(lists:sort([VC1, VC2]), lists:sort(value(timestamp, MVRMerge1))), + VC12 = riak_dt_vclock:increment(actor2, VC1), + %% Propagate a timestamp that dominates all current ones + {ok, MVRMerge2} = apply_update({propagate, {value2, VC12, nothing}}, MVRMerge1), + ?assertEqual([value2], value(MVRMerge2)), + ?assertEqual([VC12], value(timestamp, MVRMerge2)), + %% Propagate a timestamp that is dominated by the current one + {ok, MVRMerge3} = apply_update({propagate, {value3, VC1, nothing}}, MVRMerge2), + ?assertEqual([value2], value(MVRMerge3)), + ?assertEqual([VC12], value(timestamp, MVRMerge3)). + +%% @doc Check if a diverged MVReg merges all vector clocks after being updated. +update_assign_diverge_test() -> + VC0 = riak_dt_vclock:fresh(), + VC1 = riak_dt_vclock:increment(actor1, VC0), + VC2 = riak_dt_vclock:increment(actor2, VC0), + %% This represents a MVReg that have two concurrent assignment (one propagated). + MVReg0 = [{value1, VC1}, {value2, VC2}], + {ok, MVReg1} = apply_update({assign, {value3, actor1}}, MVReg0), + VC1_2 = riak_dt_vclock:increment(actor2, VC1), + VC1_3 = riak_dt_vclock:increment(actor1, VC1_2), + %% After updating, the MVReg should only have one vector clock, + %% having the maximum count of actors from each vector clock. + %% Update with actor1 (existing) + ?assert(equal([{value3, VC1_3}], MVReg1)), + {ok, MVReg2} = apply_update({assign, {value4, actor3}}, MVReg0), + VC1_4 = riak_dt_vclock:increment(actor3, VC1_2), + %% Check when updated with actor3, which was not in MVReg + ?assert(equal([{value4, VC1_4}], MVReg2)). + +%% Do we need a merge? Anyway its functionality is very similar to propagate. +%merge_test() -> +% MVReg1 = {old_value, 3}, +% MVReg2 = {new_value, 4}, +% ?assertEqual({<<>>, 0}, merge(new(), new())), +% ?assertEqual({new_value, 4}, merge(MVReg1, MVReg2)), +% ?assertEqual({new_value, 4}, merge(MVReg2, MVReg1)). + +%% @doc Check if serialization (`to_binary/1', `from_binary/1') works. +roundtrip_bin_test() -> + MVReg = new(), + {ok, MVReg1} = apply_update({assign, {2, a1}}, MVReg), + {ok, MVReg2} = apply_update({assign, {4, a2}}, MVReg1), + {ok, MVReg3} = apply_update({assign, {89, a3}}, MVReg2), + {ok, MVReg4} = apply_update({assign, {<<"this is a binary">>, a4}}, MVReg3), + Bin = to_binary(MVReg4), + {ok, Decoded} = from_binary(Bin), + ?assert(equal(MVReg4, Decoded)). + +%% @doc Check if stas return the correct size of MVReg. +stat_test() -> + MVReg = new(), + {ok, MVReg1} = apply_update({assign, {<<"abcd">>, 1}}, MVReg), + ?assertEqual([{value_size, 25}], stats(MVReg)), + ?assertEqual([{value_size, 40}], stats(MVReg1)), + ?assertEqual(40, stat(value_size, MVReg1)), + ?assertEqual(undefined, stat(actor_count, MVReg1)). + +is_operation_test() -> + ?assertEqual(true, is_operation({assign, {value, actor}})), + ?assertEqual(true, is_operation({assign, {something, 20, actor}})), + ?assertEqual(false, is_operation({assign, {something, some_value, actor}})), + ?assertEqual(false, is_operation({add, atom})), + ?assertEqual(false, is_operation({anything, [1,2,3]})). + +-endif. From 86511a172161ccc81918d8306e3b821ef7cb7e71 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 11:41:37 +0200 Subject: [PATCH 117/426] add mvreg to types --- src/antidote_crdt.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 50742e717..072613d38 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -29,7 +29,8 @@ antidote_crdt_orset, antidote_crdt_gset, antidote_crdt_rga, - antidote_crdt_bcounter + antidote_crdt_bcounter, + antidote_crdt_mvreg ]). -export([is_type/1 From 5d2be3164b5f53efd2e4e97cdf1303d8af5debd1 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 12:53:09 +0200 Subject: [PATCH 118/426] fix type check --- src/antidote_crdt_orset.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index ab0d8da1d..aaf51e145 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -256,7 +256,8 @@ is_operation({add, _Elem}) -> true; is_operation({add_all, [_H|_T]}) -> true; is_operation({remove, _Elem}) -> true; -is_operation({remove_all, [_H|_T]}) -> true. +is_operation({remove_all, [_H|_T]}) -> true; +is_operation(_) -> false. require_state_downstream({add,_}) -> false; From 6c14b3e0e7afcb86158127fb81d1404c6935254e Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 17 May 2016 13:49:13 +0200 Subject: [PATCH 119/426] set: don't add empty removes or adds --- src/antidotec_set.erl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index 27e6331dc..6edbacb13 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -98,11 +98,13 @@ is_type(T) -> type() -> set. to_ops(BoundObject, #antidote_set{adds=Adds, rems=Rems}) -> - case sets:size(Adds) =:= 0 andalso sets:size(Rems) =:= 0 of - true -> []; - false -> - [{BoundObject, add_all, sets:to_list(Adds)}, - {BoundObject, remove_all, sets:to_list(Rems)}] + R = case sets:size(Rems) > 0 of + true -> [{BoundObject, remove_all, sets:to_list(Rems)}]; + false -> [] + end, + case sets:size(Adds) > 0 of + true -> [{BoundObject, add_all, sets:to_list(Adds)} | R]; + false -> R end. From 57f6e17b0e5182d71eb987b46596ba2222704846 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Wed, 18 May 2016 13:43:33 +0200 Subject: [PATCH 120/426] map from riakdt_map --- src/antidote_crdt_map.erl | 90 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/antidote_crdt_map.erl diff --git a/src/antidote_crdt_map.erl b/src/antidote_crdt_map.erl new file mode 100644 index 000000000..a0abf60d1 --- /dev/null +++ b/src/antidote_crdt_map.erl @@ -0,0 +1,90 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc module antidote_crdt_gset - A wrapper around riak_dt_gset + +-module(antidote_crdt_map). + +-behaviour(antidote_crdt). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-define(RIAK_MODULE, riak_dt_map). + +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +-type map() :: riak_dt:riak_dt_map(). + +-type map_op() :: {update, {[map_field_update() | map_field_op()], actorordot()}}. +-type actorordot() :: riak_dt:actor() | riak_dt:dot(). + +-type map_field_op() :: {remove, field()}. +-type map_field_update() :: {update, field(), crdt_op()}. +-type crdt_op() :: term(). %% Valid riak_dt udpates +-type field() :: term(). %% riak_dt_map:field(). + +new() -> + ?RIAK_MODULE:new(). + +value(Map) -> + ?RIAK_MODULE:value(Map). + +-spec downstream(map_op(), map()) -> {ok, term()}. +downstream({Op, {OpParam, Actor}}, State) -> + {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), + {ok, {merge, S0}}. + +update({merge, State1}, State2) -> + {ok, ?RIAK_MODULE:merge(State1, State2)}. + +require_state_downstream(_Operation) -> true. + +is_operation(Operation) -> + ?RIAK_MODULE:is_operation(Operation). + +equal(CRDT1, CRDT2) -> + ?RIAK_MODULE:equal(CRDT1,CRDT2). + +to_binary(CRDT) -> + ?RIAK_MODULE:to_binary(CRDT). + +from_binary(Bin) -> + ?RIAK_MODULE:from_binary(Bin). + +-ifdef(test). +all_test() -> + S0 = new(), + Field = {'C', riak_dt_pncounter}, + {ok, Downstream} = downstream({update, {[{update, Field, {increment, 1}}], actor}}, S0), + {ok, S1} = update(Downstream, S0), + ?assertEqual([{Field, 1}], value(S1)). + +-endif. From 4534334e590550ec3065566805149e0bacee02db Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 21 Jun 2016 10:18:12 +0200 Subject: [PATCH 121/426] add lww register --- src/antidote_crdt_lwwreg.erl | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/antidote_crdt_lwwreg.erl diff --git a/src/antidote_crdt_lwwreg.erl b/src/antidote_crdt_lwwreg.erl new file mode 100644 index 000000000..1d76c0b3e --- /dev/null +++ b/src/antidote_crdt_lwwreg.erl @@ -0,0 +1,86 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc module antidote_crdt_gset - A wrapper around riak_dt_gset + +-module(antidote_crdt_lwwreg). + +-behaviour(antidote_crdt). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-define(RIAK_MODULE, riak_dt_lwwreg). + +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +-export_type([lwwreg/0, lwwreg_op/0]). + +-opaque lwwreg() :: {term(), non_neg_integer()}. + +-type lwwreg_op() :: {assign, {term(), non_neg_integer()}} | {assign, term()}. + +new() -> + ?RIAK_MODULE:new(). + +value(Set) -> + ?RIAK_MODULE:value(Set). + +-spec downstream(lwwreg_op(), lwwreg()) -> {ok, term()}. +downstream({Op, OpParam}, State) -> + Actor = ignore, % Actor is not used + {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), + {ok, {merge, S0}}. + +update({merge, State1}, State2) -> + {ok, ?RIAK_MODULE:merge(State1, State2)}. + +require_state_downstream(_Operation) -> true. + +is_operation(Operation) -> + ?RIAK_MODULE:is_operation(Operation). + +equal(CRDT1, CRDT2) -> + ?RIAK_MODULE:equal(CRDT1,CRDT2). + +to_binary(CRDT) -> + ?RIAK_MODULE:to_binary(CRDT). + +from_binary(Bin) -> + ?RIAK_MODULE:from_binary(Bin). + +-ifdef(test). +all_test() -> + S0 = new(), + {ok, Downstream} = downstream({assign, a}, S0), + {ok, S1} = update(Downstream, S0), + ?assertEqual(a, value(S1)). + +-endif. From de218703b84bd2412c31ddfc81f06886b8da1ac4 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 21 Jun 2016 10:19:09 +0200 Subject: [PATCH 122/426] fix is operation and type specs --- src/antidote_crdt_gset.erl | 6 ++++-- src/antidote_crdt_map.erl | 4 ++-- src/antidote_crdt_mvreg.erl | 17 ++++++++--------- src/antidote_crdt_orset.erl | 5 ++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/antidote_crdt_gset.erl b/src/antidote_crdt_gset.erl index 51194ac21..55d31b254 100644 --- a/src/antidote_crdt_gset.erl +++ b/src/antidote_crdt_gset.erl @@ -64,8 +64,10 @@ update({merge, State1}, State2) -> require_state_downstream(_Operation) -> true. -is_operation(Operation) -> - ?RIAK_MODULE:is_operation(Operation). +is_operation({Op, {Param, _Actor}}) -> + ?RIAK_MODULE:is_operation({Op, Param}); +is_operation(_) -> + false. equal(CRDT1, CRDT2) -> ?RIAK_MODULE:equal(CRDT1,CRDT2). diff --git a/src/antidote_crdt_map.erl b/src/antidote_crdt_map.erl index a0abf60d1..eb7e63930 100644 --- a/src/antidote_crdt_map.erl +++ b/src/antidote_crdt_map.erl @@ -67,8 +67,8 @@ update({merge, State1}, State2) -> require_state_downstream(_Operation) -> true. -is_operation(Operation) -> - ?RIAK_MODULE:is_operation(Operation). +is_operation({Op, {Param, _Actor}}) -> + ?RIAK_MODULE:is_operation({Op, Param}). equal(CRDT1, CRDT2) -> ?RIAK_MODULE:equal(CRDT1,CRDT2). diff --git a/src/antidote_crdt_mvreg.erl b/src/antidote_crdt_mvreg.erl index d070c9a89..4f929cb17 100644 --- a/src/antidote_crdt_mvreg.erl +++ b/src/antidote_crdt_mvreg.erl @@ -22,10 +22,10 @@ %% @doc %% A Multi-Value Register CRDT. -%% There are two kinds of updates: assign and propagate. Assign is use for a -%% single replica of MVReg where updates are linealizable. Propagate is used +%% There are two kinds of updates: assign and propagate. Assign is use for a +%% single replica of MVReg where updates are linealizable. Propagate is used %% to propagate update from a replica to other replicas. It is similar to the -%% 'merge' operation of the state-based specifiction of MVReg. +%% 'merge' operation of the state-based specifiction of MVReg. %% %% This file is adapted from riak_dt_lwwreg, a state-based implementation of %% last-writer-wins register. @@ -34,7 +34,7 @@ %% may contain multiple values. %% 2. There is a new kind of operation: propagate, which stands for merging the %% contents of two MVRegs. -%% +%% %% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of %% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ %% @@ -192,7 +192,7 @@ merge(MVReg1, MVReg2) -> merge(MVReg1, MVReg2, []). %% @doc Helper function of `merge/2'. It removes value entries that are descendes of -%% any other. Remainder are value entries whose vector clock is neither descendent of +%% any other. Remainder are value entries whose vector clock is neither descendent of %% any other entry nor being ascendent of any other. merge([], MVReg2, Remainder) -> MVReg2++Remainder; @@ -239,13 +239,12 @@ eq(_, _) -> stats(MVReg) -> [{value_size, stat(value_size, MVReg)}]. --spec stat(atom(), mvreg()) -> non_neg_integer() | undefined. +-spec stat(atom(), mvreg()) -> non_neg_integer(). stat(value_size, MVReg) -> Values = value(MVReg), TS = value(timestamp, MVReg), Size = erlang:external_size(Values) + erlang:external_size(TS), - Size; -stat(_, _) -> undefined. + Size. -include_lib("riak_dt/include/riak_dt_tags.hrl"). -define(DT_MVREG_TAG, 85). @@ -364,7 +363,7 @@ merge_test() -> ?assert(equal([{value2, [{actor1, 2}, {actor2, 3}]}, {value4, [{actor1, 3}, {actor2, 2}]}], MergedMVReg3)), MVReg7 = [{value3, [{actor1, 3}, {actor2, 3}]}], MergedMVReg4 = merge(MVReg5, MVReg7), - %% Merge two MVRegs that one dominates the other + %% Merge two MVRegs that one dominates the other ?assert(equal(MVReg7, MergedMVReg4)). diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index aaf51e145..19285bf16 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -180,10 +180,9 @@ precondition_context(ORDict) -> stats(ORSet) -> [ {S, stat(S, ORSet)} || S <- [element_count] ]. --spec stat(atom(), orset()) -> integer() | undefined. +-spec stat(atom(), orset()) -> integer(). stat(element_count, ORSet) -> - orddict:size(ORSet); -stat(_, _) -> undefined. + orddict:size(ORSet). -include_lib("riak_dt/include/riak_dt_tags.hrl"). -define(TAG, ?DT_ORSET_TAG). From 58f046fcfd3c36f824dc8eced87d035d0193c928 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Tue, 21 Jun 2016 10:20:52 +0200 Subject: [PATCH 123/426] fix test --- src/antidote_crdt_mvreg.erl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/antidote_crdt_mvreg.erl b/src/antidote_crdt_mvreg.erl index 4f929cb17..f19773d3f 100644 --- a/src/antidote_crdt_mvreg.erl +++ b/src/antidote_crdt_mvreg.erl @@ -493,8 +493,7 @@ stat_test() -> {ok, MVReg1} = apply_update({assign, {<<"abcd">>, 1}}, MVReg), ?assertEqual([{value_size, 25}], stats(MVReg)), ?assertEqual([{value_size, 40}], stats(MVReg1)), - ?assertEqual(40, stat(value_size, MVReg1)), - ?assertEqual(undefined, stat(actor_count, MVReg1)). + ?assertEqual(40, stat(value_size, MVReg1)). is_operation_test() -> ?assertEqual(true, is_operation({assign, {value, actor}})), From a7021decf065885e75d86ac4e3dd43f9319dd9d9 Mon Sep 17 00:00:00 2001 From: deepthidevaki Date: Thu, 30 Jun 2016 10:02:20 +0200 Subject: [PATCH 124/426] add map to supported crdts --- src/antidote_crdt.erl | 3 ++- src/antidote_crdt_map.erl | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 072613d38..beef83b4d 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -30,7 +30,8 @@ antidote_crdt_gset, antidote_crdt_rga, antidote_crdt_bcounter, - antidote_crdt_mvreg + antidote_crdt_mvreg, + antidote_crdt_map ]). -export([is_type/1 diff --git a/src/antidote_crdt_map.erl b/src/antidote_crdt_map.erl index eb7e63930..296d9595a 100644 --- a/src/antidote_crdt_map.erl +++ b/src/antidote_crdt_map.erl @@ -79,7 +79,7 @@ to_binary(CRDT) -> from_binary(Bin) -> ?RIAK_MODULE:from_binary(Bin). --ifdef(test). +-ifdef(TEST). all_test() -> S0 = new(), Field = {'C', riak_dt_pncounter}, @@ -87,4 +87,10 @@ all_test() -> {ok, S1} = update(Downstream, S0), ?assertEqual([{Field, 1}], value(S1)). +type_check_test() -> + Res = is_operation({update,{[{update,{key,riak_dt_lwwreg},{assign,<<"A">>}}, + {update,{val,riak_dt_pncounter},{increment,1}}], + hardcodedactor}}), + ?assertEqual(true, Res). + -endif. From cc28319dd396c6121e81ea023b8cdcf08f376c24 Mon Sep 17 00:00:00 2001 From: balegas Date: Tue, 30 Aug 2016 13:51:28 +0100 Subject: [PATCH 125/426] Export check permissions function. --- src/antidote_crdt_bcounter.erl | 37 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/antidote_crdt_bcounter.erl b/src/antidote_crdt_bcounter.erl index c6b351559..7a975535c 100644 --- a/src/antidote_crdt_bcounter.erl +++ b/src/antidote_crdt_bcounter.erl @@ -8,7 +8,7 @@ %% @doc %% An operation based implementation of the bounded counter CRDT. %% This counter is able to maintain a non-negative value by -%% explicitly exchanging permissions to execute decrement operations. +%% explicitly exchanging permissions to execute decrement operations. %% All operations on this CRDT are monotonic and do not keep extra tombstones. %% @end @@ -27,7 +27,8 @@ to_binary/1, from_binary/1, is_operation/1, - require_state_downstream/1 + require_state_downstream/1, + generate_downstream_check/4 ]). %% API @@ -44,7 +45,7 @@ -opaque bcounter() :: {orddict:orddict(),orddict:orddict()}. -type binary_bcounter() :: binary(). -type bcounter_op() :: bcounter_anon_op() | bcounter_src_op(). --type bcounter_anon_op() :: {transfer, {pos_integer(), id(), id()}} | +-type bcounter_anon_op() :: {transfer, {pos_integer(), id(), id()}} | {increment, {pos_integer(), id()}} | {decrement, {pos_integer(), id()}}. -type bcounter_src_op() :: {bcounter_anon_op(), id()}. -opaque id() :: term. %% A replica's identifier. @@ -56,46 +57,46 @@ new() -> %% @doc Return the available permissions of replica `Id' in a `bcounter()'. -spec localPermissions(id(),bcounter()) -> non_neg_integer(). -localPermissions(Id,{P,D}) -> +localPermissions(Id,{P,D}) -> Received = lists:foldl( fun( {_,V},Acc) -> - Acc + V + Acc + V end, 0, orddict:filter( fun( {_,To},_) when To == Id -> - true; + true; (_,_) -> - false + false end, P)), Granted = lists:foldl( fun ({_,V},Acc) -> - Acc + V + Acc + V end, 0, orddict:filter( fun ({From,To},_) when From == Id andalso To /= Id -> true; (_,_) -> - false + false end, P)), case orddict:find(Id,D) of - {ok, Decrements} -> + {ok, Decrements} -> Received - Granted - Decrements; - error -> + error -> Received - Granted end. %% @doc Return the total available permissions in a `bcounter()'. -spec permissions(bcounter()) -> non_neg_integer(). -permissions({P,D}) -> +permissions({P,D}) -> TotalIncrements = orddict:fold( fun ({K,K},V,Acc) -> - V + Acc; + V + Acc; (_,_,Acc) -> - Acc + Acc end, 0, P), TotalDecrements = orddict:fold( fun @@ -146,15 +147,15 @@ update({{transfer, V,To},From}, Counter) -> transfer(From,To,V,Counter). %% Add a given amount of permissions to a replica. -increment(Id,V,{P,D}) -> +increment(Id,V,{P,D}) -> {ok,{orddict:update_counter({Id,Id},V,P),D}}. %% Consume a given amount of permissions from a replica. -decrement(Id,V,{P,D}) -> +decrement(Id,V,{P,D}) -> {ok, {P,orddict:update_counter(Id,V,D)}}. %% Transfer a given amount of permissions from one replica to another. -transfer(From,To,V,{P,D}) -> +transfer(From,To,V,{P,D}) -> {ok, {orddict:update_counter({From,To},V,P),D}}. %% doc Return the binary representation of a `bcounter()'. @@ -221,7 +222,7 @@ localPermisisons_test() -> ?assertEqual(10, localPermissions(r1,Counter1)), %% Test nonexistent replica. ?assertEqual(0, localPermissions(r2,Counter1)). - + %% Tests decrement operations. decrement_test() -> Counter0 = new(), From 698a20e84f28b747d76d439c0f82be5058b19d89 Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Sat, 3 Sep 2016 22:14:33 +0200 Subject: [PATCH 126/426] Added gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..6770f4b73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.local_dialyzer_plt +deps/ +ebin/ \ No newline at end of file From ab2c7b66ae7b93355b948531a611298297ec0a9c Mon Sep 17 00:00:00 2001 From: Annette Bieniusa Date: Sat, 3 Sep 2016 22:36:39 +0200 Subject: [PATCH 127/426] Re-added the specs --- src/antidotec_pb.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index be13a5f4b..242f24bef 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -31,7 +31,7 @@ -define(TIMEOUT, 10000). -spec start_transaction(Pid::term(), TimeStamp::term(), TxnProperties::term()) - -> {ok,{interactive,term()} | {static,{term(),term()}}} | {error, term()}. + -> {ok, {interactive, term()} | {static, {term(), term()}}} | {error, term()}. start_transaction(Pid, TimeStamp, TxnProperties) -> case is_static(TxnProperties) of true -> @@ -89,7 +89,7 @@ commit_transaction(Pid, {static, _TxId}) -> {ok, CommitTime} end. -%%-spec update_objects(Pid::term(), Updates::[{bound_object(), op(), op_parm()}], TxId::term()) -> ok | {error, term()}. +-spec update_objects(Pid::term(), Updates::[{term(), term(), term()}], TxId::term()) -> ok | {error, term()}. update_objects(Pid, Updates, {interactive, TxId}) -> EncMsg = antidote_pb_codec: encode(update_objects, {Updates, TxId}), Result = antidotec_pb_socket: call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), @@ -119,10 +119,10 @@ update_objects(Pid, Updates, {static, TxId}) -> end end. - +-spec read_objects(Pid::term(), Objects::[term()], TxId::term()) -> {ok, [term()]} | {error, term()}. read_objects(Pid, Objects, {interactive, TxId}) -> EncMsg = antidote_pb_codec:encode(read_objects, {Objects, TxId}), - Result = antidotec_pb_socket:call_infinity(Pid,{req, EncMsg, ?TIMEOUT}), + Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), case Result of {error, timeout} -> {error, timeout}; _ -> From 982f351c06ec9902fd41f5b976d144e05e15052f Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Tue, 6 Sep 2016 16:24:14 +0200 Subject: [PATCH 128/426] set datatype is no longer builtin since erlang 18 --- src/antidotec_set.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index 6edbacb13..b7ddf1f1b 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -38,9 +38,9 @@ ]). -record(antidote_set, { - set :: set(), - adds :: set(), - rems :: set() + set :: sets:set(), + adds :: sets:set(), + rems :: sets:set() }). -export_type([antidote_set/0]). From f036629f87d914c1e62a0fc548b4b378415ce1e8 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Tue, 6 Sep 2016 16:24:36 +0200 Subject: [PATCH 129/426] fixed dependencies for erlang 19 --- rebar.config | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rebar.config b/rebar.config index f242d5a37..705284b4b 100644 --- a/rebar.config +++ b/rebar.config @@ -2,10 +2,14 @@ {sub_dirs, ["rel"]}. {deps, [ - {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "2.0.3"}}}, - {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {tag, "antidote"}}} + {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "3.2.1"}}}, + {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {branch, "antidote_crdt_rebar3"}}} ]}. +{plugins, [ + {protobuffs, {git, "git://github.com/basho/erlang_protobuffs.git", {tag, "0.9.0"}}} + ]}. + {erl_opts, [debug_info, warnings_as_errors, {parse_transform, lager_transform}]}. {cover_enabled, true}. -{eunit_opts, [verbose, {report, {eunit_surefire, [{dir,"."}]}}]}. \ No newline at end of file +{eunit_opts, [verbose, {report, {eunit_surefire, [{dir,"."}]}}]}. From 5e55f5125f2e9181acdaf6710c28e41d03479cb8 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Tue, 6 Sep 2016 16:32:35 +0200 Subject: [PATCH 130/426] map is now a builtin type --- src/antidote_crdt_map.erl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/antidote_crdt_map.erl b/src/antidote_crdt_map.erl index 296d9595a..06e8a4670 100644 --- a/src/antidote_crdt_map.erl +++ b/src/antidote_crdt_map.erl @@ -41,7 +41,6 @@ require_state_downstream/1 ]). --type map() :: riak_dt:riak_dt_map(). -type map_op() :: {update, {[map_field_update() | map_field_op()], actorordot()}}. -type actorordot() :: riak_dt:actor() | riak_dt:dot(). @@ -57,7 +56,7 @@ new() -> value(Map) -> ?RIAK_MODULE:value(Map). --spec downstream(map_op(), map()) -> {ok, term()}. +-spec downstream(map_op(), riak_dt:riak_dt_map()) -> {ok, term()}. downstream({Op, {OpParam, Actor}}, State) -> {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), {ok, {merge, S0}}. From 1910588d7ad5de1aab120517ba7151e4f0338028 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Wed, 28 Sep 2016 18:27:15 +0200 Subject: [PATCH 131/426] added proper(ty) based tests - general framework to test specifications - example tests for counter and orset --- .gitignore | 2 + rebar.config | 7 ++ test/crdt_properties.erl | 145 +++++++++++++++++++++++++++++++++++++ test/prop_crdt_counter.erl | 40 ++++++++++ test/prop_crdt_orset.erl | 52 +++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 .gitignore create mode 100644 test/crdt_properties.erl create mode 100644 test/prop_crdt_counter.erl create mode 100644 test/prop_crdt_orset.erl diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..d11b20bab --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +_build/ +test/.rebar3/ \ No newline at end of file diff --git a/rebar.config b/rebar.config index b00a0f5bb..f6479ba36 100644 --- a/rebar.config +++ b/rebar.config @@ -9,3 +9,10 @@ {eunit_opts, [verbose]}. {xref_checks, [undefined_function_calls]}. {edoc_opts, [{preprocess, true}]}. + + +{plugins, [rebar3_proper]}. + +{profiles, + [{test, [{deps, [{proper, "1.1.1-beta"}]}]}] +}. \ No newline at end of file diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl new file mode 100644 index 000000000..c0a4617d4 --- /dev/null +++ b/test/crdt_properties.erl @@ -0,0 +1,145 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(crdt_properties). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + + + +-export([crdt_satisfies_spec/3, clock_le/2]). + +-export_type([clocked_operation/0]). + + + +-type clock() :: #{replica() => non_neg_integer()}. +-type clocked_operation() :: {Clock :: clock(), Operation :: any()}. +-type clocked_effect() :: {Clock :: clock(), Effect :: any()}. +-type replica() :: dc1 | dc2 | dc3. + +-record(test_replica_state, { + state :: any(), + clock = #{} :: clock(), + operations = [] :: [clocked_operation()], + downstreamOps = [] :: [clocked_effect()] +}). + +-type test_replica_state() :: #test_replica_state{}. +-type test_state() :: #{replica() => test_replica_state()}. +-type test_operation() :: {pull, replica(), replica()} | {exec, replica(), any()}. + + +%% this checks whether the implementation satisfies a given CRDT specification +%% Crdt: module name of the CRDT to test +%% OperationGen: proper generator for generating a single random CRDT operation +%% Spec: A function which takes a list of {Clock,Operation} pairs. The clock can be used to determine the happens-before relation between operations +-spec crdt_satisfies_spec(atom(), fun(() -> proper_types:raw_type()), fun(([clocked_operation()]) -> boolean())) -> proper:forall_clause(). +crdt_satisfies_spec(Crdt, OperationGen, Spec) -> + ?FORALL(Ops, generateOps(OperationGen), + checkSpec(Crdt, Ops, Spec) + ). + + + +% generates a list of operations +generateOps(OpGen) -> + list(oneof([ + % pulls one operation from the first replica to the second + {pull, replica(), replica()}, + % execute operation on a given replica + {exec, replica(), OpGen()} + ])). + +replica() -> oneof([dc1, dc2, dc3]). + +clock_le(A, B) -> + lists:all(fun(R) -> maps:get(R, A) =< maps:get(R, B, 0) end, maps:keys(A)). + + +% executes/checks the specification +checkSpec(Crdt, Ops, Spec) -> + InitialState = maps:from_list( + [{Dc, #test_replica_state{state = Crdt:new()}} || Dc <- [dc1, dc2, dc3]]), + EndState = execSystem(Crdt, Ops, InitialState), + lists:all(fun(R) -> checkSpecEnd(Crdt, Spec, EndState, R) end, maps:keys(EndState)). + +checkSpecEnd(Crdt, Spec, EndState, R) -> + RState = maps:get(R, EndState), + RClock = RState#test_replica_state.clock, + RValue = Crdt:value(RState#test_replica_state.state), + + % get the visible operations: + VisibleOperations = [{Clock, Op} || + Replica <- maps:keys(EndState), + {Clock, Op} <- (maps:get(Replica, EndState))#test_replica_state.operations, + clock_le(Clock, RClock)], + + SpecValue = Spec(VisibleOperations), + SpecValue == RValue. + + +-spec execSystem(atom(), [test_operation()], test_state()) -> test_state(). +execSystem(_Crdt, [], State) -> + State; +execSystem(Crdt, [{pull, Source, Target}|RemainingOps], State) -> + TargetState = maps:get(Target, State), + TargetClock = TargetState#test_replica_state.clock, + SourceState = maps:get(Source, State), + % get all downstream operations at the source, which are not yet delivered to the target, + % and which have all dependencies already delivered at the target + Effects = [{Clock, Effect} || + {Clock, Effect} <- SourceState#test_replica_state.downstreamOps, + not clock_le(Clock, TargetClock), + clock_le(Clock#{Source => 0}, TargetClock) + ], + NewState = + case Effects of + [] -> State; + [{Clock, Op}|_] -> + {ok, NewCrdtState} = Crdt:update(Op, TargetState#test_replica_state.state), + NewTargetState = TargetState#test_replica_state{ + state = NewCrdtState, + clock = TargetClock#{Source => maps:get(Source, Clock)} + }, + State#{Target => NewTargetState} + end, + + + execSystem(Crdt, RemainingOps, NewState); +execSystem(Crdt, [{exec, Replica, Op}|RemainingOps], State) -> + ReplicaState = maps:get(Replica, State), + CrdtState = ReplicaState#test_replica_state.state, + {ok, Effect} = Crdt:downstream(Op, CrdtState), + {ok, NewCrdtState} = Crdt:update(Effect, CrdtState), + + ReplicaClock = ReplicaState#test_replica_state.clock, + NewReplicaClock = ReplicaClock#{Replica => maps:get(Replica, ReplicaClock, 0) + 1}, + + NewReplicaState = ReplicaState#test_replica_state{ + state = NewCrdtState, + clock = NewReplicaClock, + operations = ReplicaState#test_replica_state.operations ++ [{NewReplicaClock, Op}], + downstreamOps = ReplicaState#test_replica_state.downstreamOps ++ [{NewReplicaClock, Effect}] + }, + NewState = State#{Replica => NewReplicaState}, + execSystem(Crdt, RemainingOps, NewState). + diff --git a/test/prop_crdt_counter.erl b/test/prop_crdt_counter.erl new file mode 100644 index 000000000..fb950f0bf --- /dev/null +++ b/test/prop_crdt_counter.erl @@ -0,0 +1,40 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_counter). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_counter_spec/0]). + + +prop_counter_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_counter, fun counter_op/0, fun counter_spec/1). + + +counter_spec(Operations) -> + lists:sum([X || {_, {increment, X}} <- Operations]) - lists:sum([X || {_, {decrement, X}} <- Operations]). + +% generates a random counter operation +counter_op() -> + tuple([oneof([increment, decrement]), non_neg_integer()]). + diff --git a/test/prop_crdt_orset.erl b/test/prop_crdt_orset.erl new file mode 100644 index 000000000..9c11a47ec --- /dev/null +++ b/test/prop_crdt_orset.erl @@ -0,0 +1,52 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_orset). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_orset_spec/0]). + + +prop_orset_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_orset, fun set_op/0, fun add_wins_set_spec/1). + + +add_wins_set_spec(Operations) -> + lists:usort( + % all X, + [X || + % such that there is an add operation for X + {AddClock, {add, X}} <- Operations, + % and there is no remove operation after the add + [] == [Y || {RemoveClock, {remove, Y}} <- Operations, X == Y, crdt_properties:clock_le(AddClock, RemoveClock)] + ]). + +% generates a random counter operation +set_op() -> + oneof([ + {add, set_element()}, + {remove, set_element()} + ]). + +set_element() -> + oneof([a,b]). \ No newline at end of file From 99ebdb4a3155fa5b5627b74ae1964651da8c9d7f Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Wed, 28 Sep 2016 18:28:33 +0200 Subject: [PATCH 132/426] fixed bug in orset failed for concurrent removes (see testcase) --- src/antidote_crdt_orset.erl | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 19285bf16..ce08c4670 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -221,15 +221,10 @@ remove_elem({Elem,RemoveTokens},ORDict) -> [] -> {ok, orddict:erase(Elem, ORDict)}; _ -> - {ok, orddict:store(Elem, Tokens--RemoveTokens, ORDict)} + {ok, orddict:store(Elem, RestTokens, ORDict)} end; error -> - case RemoveTokens of - [] -> - {ok, ORDict}; - _ -> - {error, {precondition, {not_present, Elem}}} - end + {ok, ORDict} end. remove_elems([], ORDict) -> @@ -329,6 +324,26 @@ remove_test() -> ?assertMatch({ok, _}, Result). +remove2_test() -> + Set1 = new(), + %% Add an element then remove it + {ok, Op1} = downstream({add, <<"foo">>}, Set1), + {ok, Set2} = update(Op1, Set1), + ?assertEqual([<<"foo">>], value(Set2)), + {ok, Op2} = downstream({remove, <<"foo">>}, Set2), + {ok, Set3} = update(Op2, Set2), + ?assertEqual([], value(Set3)), + + %% Remove the element again (e.g. on a different replica) + {ok, Op3} = downstream({remove, <<"foo">>}, Set2), + {ok, Set4} = update(Op3, Set2), + ?assertEqual([], value(Set4)), + + %% now execute Op3 on Set3, where the element was already removed locally + {ok, Set5} = update(Op3, Set3), + ?assertEqual([], value(Set5)). + + concurrent_add_test() -> Set1 = new(), %% Add an element then remove it From 0aba92f8fa72fdd08e363748cca3f4008fda0a61 Mon Sep 17 00:00:00 2001 From: "Alejandro Z. Tomsic" Date: Fri, 30 Sep 2016 10:19:22 +0200 Subject: [PATCH 133/426] added antidote_crdt_lwwreg to the list of valid crdts, needed for type check --- src/antidote_crdt.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index beef83b4d..6cf27050a 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -31,7 +31,8 @@ antidote_crdt_rga, antidote_crdt_bcounter, antidote_crdt_mvreg, - antidote_crdt_map + antidote_crdt_map, + antidote_crdt_lwwreg ]). -export([is_type/1 From ffad302d430133fea559380c8d23800a179c5762 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 13:55:49 +0200 Subject: [PATCH 134/426] fixed dialyzer problem --- src/antidote_crdt_orset.erl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index ce08c4670..2d5a32f2a 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -230,10 +230,8 @@ remove_elem({Elem,RemoveTokens},ORDict) -> remove_elems([], ORDict) -> {ok, ORDict}; remove_elems([Elem|Rest], ORDict) -> - case remove_elem(Elem,ORDict) of - {ok, ORDict1} -> remove_elems(Rest, ORDict1); - Error -> Error - end. + {ok, ORDict1} = remove_elem(Elem,ORDict), + remove_elems(Rest, ORDict1). %% @doc generate a unique identifier (best-effort). unique() -> From 5722866d12c238f56eac40c8f1849a181d79f8a9 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 14:04:09 +0200 Subject: [PATCH 135/426] operation based lwwreg --- src/antidote_crdt_lwwreg.erl | 40 +++++++++++++++---------- test/prop_crdt_lwwreg.erl | 57 ++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 test/prop_crdt_lwwreg.erl diff --git a/src/antidote_crdt_lwwreg.erl b/src/antidote_crdt_lwwreg.erl index 1d76c0b3e..c36cf856b 100644 --- a/src/antidote_crdt_lwwreg.erl +++ b/src/antidote_crdt_lwwreg.erl @@ -43,38 +43,46 @@ -export_type([lwwreg/0, lwwreg_op/0]). --opaque lwwreg() :: {term(), non_neg_integer()}. +-opaque lwwreg() :: {non_neg_integer(), term()}. --type lwwreg_op() :: {assign, {term(), non_neg_integer()}} | {assign, term()}. +-type lwwreg_op() :: {assign, term(), non_neg_integer()} | {assign, term()}. new() -> - ?RIAK_MODULE:new(). + {0, <<>>}. -value(Set) -> - ?RIAK_MODULE:value(Set). +value({_Time, Val}) -> + Val. -spec downstream(lwwreg_op(), lwwreg()) -> {ok, term()}. -downstream({Op, OpParam}, State) -> - Actor = ignore, % Actor is not used - {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), - {ok, {merge, S0}}. +downstream({assign, Value, Time}, {OldTime, _OldValue}) -> + {ok, {max(Time, OldTime+1), Value}}; +downstream({assign, Value}, State) -> + downstream({assign, Value, make_micro_epoch()}, State). + +make_micro_epoch() -> + {Mega, Sec, Micro} = os:timestamp(), + (Mega * 1000000 + Sec) * 1000000 + Micro. + + +update(Effect, State) -> + % take the state with maximum time, if times are equal use maximum state + {ok, max(Effect, State)}. -update({merge, State1}, State2) -> - {ok, ?RIAK_MODULE:merge(State1, State2)}. require_state_downstream(_Operation) -> true. -is_operation(Operation) -> - ?RIAK_MODULE:is_operation(Operation). +is_operation({assign, _Value}) -> true; +is_operation(_Other) -> false. + equal(CRDT1, CRDT2) -> - ?RIAK_MODULE:equal(CRDT1,CRDT2). + CRDT1 == CRDT2. to_binary(CRDT) -> - ?RIAK_MODULE:to_binary(CRDT). + erlang:term_to_binary(CRDT). from_binary(Bin) -> - ?RIAK_MODULE:from_binary(Bin). + erlang:binary_to_term(Bin). -ifdef(test). all_test() -> diff --git a/test/prop_crdt_lwwreg.erl b/test/prop_crdt_lwwreg.erl new file mode 100644 index 000000000..8971c4fbd --- /dev/null +++ b/test/prop_crdt_lwwreg.erl @@ -0,0 +1,57 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_lwwreg). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_counter_spec/0]). + + +prop_counter_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_lwwreg, fun op/0, fun spec/1). + + +spec(Operations) -> + case Operations of + [] -> + % initial value is empty binary + <<>>; + _ -> + % times are corrected, so that old values are always overridden + Operations2 = [correctTime(Operations, Op) || Op <- Operations], + % select the value based on the assign with maximum timestamp (or max. value if timestamps are equal) + {_MaxTime, MaxVal} = lists:max([{Time, Val} || {_, {assign, Val, Time}} <- Operations2]), + MaxVal + end. + +correctTime(Operations, {OperationVc, {assign, Value, Timestamp}}) -> + Before = [{Vc,Op} || {Vc,Op} <- Operations, Vc =/= OperationVc, crdt_properties:clock_le(Vc, OperationVc)], + Before2 = [correctTime(Before, Op) || Op <- Before], + BeforeTimestampMax = lists:max([0] ++ [T || {_, {assign, _, T}} <- Before2]), + {OperationVc, {assign, Value, max(Timestamp, BeforeTimestampMax+1) }}. + + +% generates a random counter operation +op() -> + {assign, oneof([a,b,c,d,e,f,g,h,i]), non_neg_integer()}. + From 5202709fef38248d6d72532ec295d4aaf3cc1cae Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 14:10:34 +0200 Subject: [PATCH 136/426] updated lwwreg documentation --- src/antidote_crdt_lwwreg.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/antidote_crdt_lwwreg.erl b/src/antidote_crdt_lwwreg.erl index c36cf856b..af757b251 100644 --- a/src/antidote_crdt_lwwreg.erl +++ b/src/antidote_crdt_lwwreg.erl @@ -18,7 +18,11 @@ %% %% ------------------------------------------------------------------- -%% @doc module antidote_crdt_gset - A wrapper around riak_dt_gset +%% @doc module antidote_crdt_lwwreg - An operation based last-writer-wins register +%% Each operation is assigned a timestamp, which is guaranteed to be greater than +%% the current timestamp. +%% The current value of the register is the value assigned with the greatest timestamp +%% or the empty binary if there was no assignment yet. -module(antidote_crdt_lwwreg). From b2e0405c35bc590eeb2a8eaefea083fe6fd60685 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 14:21:51 +0200 Subject: [PATCH 137/426] lwwreg: removed riak module --- src/antidote_crdt_lwwreg.erl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/antidote_crdt_lwwreg.erl b/src/antidote_crdt_lwwreg.erl index af757b251..267e616fc 100644 --- a/src/antidote_crdt_lwwreg.erl +++ b/src/antidote_crdt_lwwreg.erl @@ -32,8 +32,6 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --define(RIAK_MODULE, riak_dt_lwwreg). - -export([ new/0, value/1, downstream/2, From 2085d8ab3d689a7ea0fc62fe308f2d330b124312 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 14:25:22 +0200 Subject: [PATCH 138/426] corrected test-name --- test/prop_crdt_lwwreg.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/prop_crdt_lwwreg.erl b/test/prop_crdt_lwwreg.erl index 8971c4fbd..514eb485c 100644 --- a/test/prop_crdt_lwwreg.erl +++ b/test/prop_crdt_lwwreg.erl @@ -24,10 +24,10 @@ -include_lib("proper/include/proper.hrl"). %% API --export([prop_counter_spec/0]). +-export([prop_lwwreg_spec/0]). -prop_counter_spec() -> +prop_lwwreg_spec() -> crdt_properties:crdt_satisfies_spec(antidote_crdt_lwwreg, fun op/0, fun spec/1). From 4a729277d02bcf88a50922fd49d8bb5a0b2e0b8a Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 14:25:33 +0200 Subject: [PATCH 139/426] operation based gset --- src/antidote_crdt_gset.erl | 46 +++++++++++++++++------------------- test/prop_crdt_gset.erl | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 test/prop_crdt_gset.erl diff --git a/src/antidote_crdt_gset.erl b/src/antidote_crdt_gset.erl index 55d31b254..22db59094 100644 --- a/src/antidote_crdt_gset.erl +++ b/src/antidote_crdt_gset.erl @@ -18,7 +18,7 @@ %% %% ------------------------------------------------------------------- -%% @doc module antidote_crdt_gset - A wrapper around riak_dt_gset +%% @doc module antidote_crdt_gset - An operation based grow-only set -module(antidote_crdt_gset). @@ -28,8 +28,6 @@ -include_lib("eunit/include/eunit.hrl"). -endif. --define(RIAK_MODULE, riak_dt_gset). - -export([ new/0, value/1, downstream/2, @@ -41,47 +39,47 @@ require_state_downstream/1 ]). --type gset() :: riak_dt_gset:gset(). --type gset_op() :: {add, {member(), actor()}} | {remove, {member(), actor()}} | - {add_all, {[member()], actor()}} | {remove_all, {[member()], actor()}}. +-type gset() :: ordsets:ordset(member()). +-type gset_op() :: {add, member()} + | {add_all, [member()]}. +-type gset_effect() :: gset(). -type member() :: term(). --type actor() :: riak_dt:actor(). new() -> - ?RIAK_MODULE:new(). + ordsets:new(). value(Set) -> - ?RIAK_MODULE:value(Set). + Set. --spec downstream(gset_op(), gset()) -> {ok, term()}. -downstream({Op, {OpParam, Actor}}, State) -> - {ok, S0} = ?RIAK_MODULE:update({Op, OpParam}, Actor, State), - {ok, {merge, S0}}. +-spec downstream(gset_op(), gset()) -> {ok, gset_effect()}. +downstream({add, Elem}, _State) -> + ordsets:from_list([Elem]); +downstream({add_all, Elems}, _State) -> + ordsets:from_list(Elems). -update({merge, State1}, State2) -> - {ok, ?RIAK_MODULE:merge(State1, State2)}. +update(Effect, State) -> + ordsets:union(State, Effect). -require_state_downstream(_Operation) -> true. +require_state_downstream(_Operation) -> false. -is_operation({Op, {Param, _Actor}}) -> - ?RIAK_MODULE:is_operation({Op, Param}); -is_operation(_) -> - false. +is_operation({add, _}) -> true; +is_operation({add_all, _}) -> true; +is_operation(_) -> false. equal(CRDT1, CRDT2) -> - ?RIAK_MODULE:equal(CRDT1,CRDT2). + CRDT1 == CRDT2. to_binary(CRDT) -> - ?RIAK_MODULE:to_binary(CRDT). + erlang:term_to_binary(CRDT). from_binary(Bin) -> - ?RIAK_MODULE:from_binary(Bin). + erlang:binary_to_term(Bin). -ifdef(test). all_test() -> S0 = new(), - {ok, Downstream} = downstream({add, {a, actor}}, S0), + {ok, Downstream} = downstream({add, a}, S0), {ok, S1} = update(Downstream, S0), ?assertEqual(1, riak_dt_gset:stat(element_count, S1)). diff --git a/test/prop_crdt_gset.erl b/test/prop_crdt_gset.erl new file mode 100644 index 000000000..76131b87f --- /dev/null +++ b/test/prop_crdt_gset.erl @@ -0,0 +1,48 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_gset). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_gset_spec/0]). + + +prop_gset_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_orset, fun set_op/0, fun add_wins_set_spec/1). + + +add_wins_set_spec(Operations) -> + lists:usort( + [X || {_, {add, X}} <- Operations] + ++ [X || {_, {add_all, Xs}} <- Operations, X <- Xs] + ). + +% generates a random counter operation +set_op() -> + oneof([ + {add, set_element()}, + {add_all, list(set_element())} + ]). + +set_element() -> + oneof([a,b,c,d]). \ No newline at end of file From 2ee6e60ca2fbfd3fbbda0b10822f6af307c048d4 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 15:46:48 +0200 Subject: [PATCH 140/426] operation based multi-value registers no more actor-Ids required in the operations --- src/antidote_crdt_mvreg.erl | 459 ++++-------------------------------- test/prop_crdt_mvreg.erl | 45 ++++ 2 files changed, 91 insertions(+), 413 deletions(-) create mode 100644 test/prop_crdt_mvreg.erl diff --git a/src/antidote_crdt_mvreg.erl b/src/antidote_crdt_mvreg.erl index f19773d3f..171b499e0 100644 --- a/src/antidote_crdt_mvreg.erl +++ b/src/antidote_crdt_mvreg.erl @@ -22,21 +22,12 @@ %% @doc %% A Multi-Value Register CRDT. -%% There are two kinds of updates: assign and propagate. Assign is use for a -%% single replica of MVReg where updates are linealizable. Propagate is used -%% to propagate update from a replica to other replicas. It is similar to the -%% 'merge' operation of the state-based specifiction of MVReg. +%% Read Returns a sorted list of all concurrently added values %% -%% This file is adapted from riak_dt_lwwreg, a state-based implementation of -%% last-writer-wins register. -%% The changes are as follows: -%% 1. The return value of an MVReg is a list of {value, vclock} pairs, as MVReg -%% may contain multiple values. -%% 2. There is a new kind of operation: propagate, which stands for merging the -%% contents of two MVRegs. -%% -%% @reference Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011) A comprehensive study of -%% Convergent and Commutative Replicated Data Types. http://hal.upmc.fr/inria-00555588/ +%% This is implemented, by assigning a unique token to every assign operation. +%% The downstream effect carries the tokens of overridden values, so that +%% only assignments, which happened before are really overridden and +%% concurrent assignments are maintained %% %% @end @@ -56,13 +47,6 @@ require_state_downstream/1 ]). --export([parent_clock/2, - value/2, - init/2, - stats/1, - to_binary/2, - to_version/2 - ]). -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). @@ -71,435 +55,84 @@ -export_type([mvreg/0, mvreg_op/0]). %% TODO: make opaque --type actor() :: term(). --type ts() :: non_neg_integer(). --type mvreg() :: [{term(), riak_dt_vclock:vclock()}]. +-type mvreg() :: [{term(), uniqueToken()}]. +-type uniqueToken() :: term(). +-type mvreg_effect() :: {Value::term(), uniqueToken(), Overridden::[uniqueToken()]}. --type mvreg_op() :: {assign, {term(), ts()}} - | {assign, term()} - | {propagate, {term(), ts()}}. --type mv_q() :: timestamp. +-type mvreg_op() :: {assign, term()}. + %% @doc Create a new, empty `mvreg()' -spec new() -> mvreg(). new() -> - [{<<>>, riak_dt_vclock:fresh()}]. + []. --spec init(term(), riak_dt_vclock:vclock()) -> mvreg(). -init(Value, VC) -> - [{Value, VC}]. --spec parent_clock(riak_dt_vclock:vclock(), mvreg()) -> mvreg(). -parent_clock(_Clock, Reg) -> - Reg. %% @doc The values of this `mvreg()'. Multiple values can be returned, %% since there can be diverged value in this register. -spec value(mvreg()) -> [term()]. value(MVReg) -> - [Val || {Val, _VC} <- MVReg]. - -%% @doc query for this `mvreg()' of its timestamp. -%% `timestamp' is the only query option. --spec value(mv_q(), mvreg()) -> [riak_dt_vclock:vclock()]. -value(timestamp, MVReg) -> - [VC || {_Val, VC} <- MVReg]. - -%% @doc Assign `Value' to this register. The vector clock of this -%% register will be incremented by one for the corresponding `Actor'. -%% In case the register has multiple diverged values, firstly a vector -%% clock that dominates all of them is calculated, then incrementation -%% for `Actor' is applied. -%% -%% This kind of update is supposed to be linealizable so the operation -%% issuer does not need to provide the vector clock it has observed. --spec downstream(mvreg_op(), mvreg()) -> {ok, term()}. -downstream({assign, {Value, Actor}}, MVReg) -> - VV = inc_vv(MVReg, Actor), - NewMVReg = [{Value, VV}], - {ok, {merge, NewMVReg}}; - -%% @doc Assign a `Value' to the `mvreg()' associating the update with -%% time `TS', if `TS' is larger than the current timestamp for `Actor'. -downstream({assign, {Value, TS, Actor}}, MVReg) -> - case larger_than(TS, Actor, MVReg) of - true -> - VV = inc_vv(MVReg, Actor), - NewMVReg = init(Value, VV), - downstream({assign, {Value, TS, Actor}}, NewMVReg); - false -> - {ok, {merge, MVReg}} - end; - -%% @doc Propagate the `Value' of a `mvreg()' to other replicas. The -%% `Value' and its vector clock `TS' is the parameter. It is assumed -%% that propagation only happens after one update is applied, therefore -%% `Value' is a single term and `TS' can only be one vector clock. All -%% compatible vector clocks (being descendent of another) will be -%% merged; non-compatible vector clocks will be kept in a list. -%% Corresponding values of non-compatible vector clocks will also be -%% kept. -downstream({propagate, {Value, TS, _Actor}}, MVReg ) -> - {ok, {merge, merge(MVReg, init(Value, TS))}}. - -update({merge, MVreg1}, MVreg2) -> - {ok, merge(MVreg1, MVreg2)}. - -%% @doc Find a least-uppder bound for all non-compatible vector clocks -%% in MVReg (if there is any) and then increment timestamp for `Actor' -%% by one. --spec inc_vv(mvreg(), actor()) -> riak_dt_vclock:vclock(). -inc_vv(MVReg, Actor) -> - VCL = [VC || {_Val, VC} <- MVReg], - [H|T] = VCL, - MaxVC = lists:foldl(fun(VC, Acc) -> riak_dt_vclock:merge([VC, Acc]) end, H, T), - NewVC = riak_dt_vclock:increment(Actor, MaxVC), - NewVC. - -%% @doc If `TS'(timestamp) is larger than all entries of `Actor' for the -%% MVReg. --spec larger_than(ts(), actor(), mvreg()) -> boolean(). -larger_than(_TS, _Actor, []) -> - true; -larger_than(TS, Actor, [H|T]) -> - {_Value, VC} = H, - OldTS = riak_dt_vclock:get_counter(Actor, VC), - case TS > OldTS of - true -> - larger_than(TS, Actor, T); - false -> - false - end. - -%% @doc If any timestamp in the first list descends the second vector clock. --spec if_descends([riak_dt_vclock:vclock()], riak_dt_vclock:vclock()) -> boolean(). -if_descends([], _VC) -> - false; -if_descends([H|T], VC) -> - case riak_dt_vclock:descends(H, VC) of - true -> - true; - false -> - if_descends(T, VC) - end. - - -%% @doc Merge two `mvreg()'s to a single `mvreg()'. This is the Least Upper Bound -%% function described in the literature. --spec merge(mvreg(), mvreg()) -> mvreg(). -merge(MVReg1, MVReg2) -> - merge(MVReg1, MVReg2, []). - -%% @doc Helper function of `merge/2'. It removes value entries that are descendes of -%% any other. Remainder are value entries whose vector clock is neither descendent of -%% any other entry nor being ascendent of any other. -merge([], MVReg2, Remainder) -> - MVReg2++Remainder; -merge(MVReg1, [], Remainder) -> - MVReg1++Remainder; -merge(MVReg1, MVReg2, Remainder) -> - {_, HVC} = hd(MVReg2), - case if_descends(value(timestamp, MVReg1), HVC) of - true -> - merge(MVReg1, tl(MVReg2), Remainder); - false -> - NewMVReg1 = lists:filter(fun({_, ElemVC}) -> riak_dt_vclock:descends(HVC, ElemVC) == false end, MVReg1), - merge(NewMVReg1, tl(MVReg2), Remainder++[hd(MVReg2)]) - end. - -%% @doc Are two `mvreg()'s structurally equal? This is not `value/1' equality. -%% Two registers might represent the value `armchair', and not be `equal/2'. Equality here is -%% that both registers contain the same value and timestamp. + [V || {V,_} <- MVReg]. + + +-spec downstream(mvreg_op(), mvreg()) -> {ok, mvreg_effect()}. +downstream({assign, Value}, MVReg) -> + Token = unique(), + Overridden = [Tok || {_, Tok} <- MVReg], + {ok, {Value, Token, Overridden}}. + +-spec unique() -> uniqueToken(). +unique() -> + crypto:strong_rand_bytes(20). + + +-spec update(mvreg_effect(), mvreg()) -> {ok, mvreg()}. +update({Value, Token, Overridden}, MVreg) -> + % remove overridden values + MVreg2 = [{V,T} || {V,T} <- MVreg, not lists:member(T, Overridden)], + % insert new value + {ok, insertSorted({Value, Token}, MVreg2)}. + +% insert value into sorted list +insertSorted(A, []) -> [A]; +insertSorted(A, [X|Xs]) when A < X -> [A,X|Xs]; +insertSorted(A, [X|Xs]) -> [X|insertSorted(A,Xs)]. + + -spec equal(mvreg(), mvreg()) -> boolean(). equal(MVReg1, MVReg2) -> - eq(lists:sort(MVReg1), lists:sort(MVReg2)). - -%% @doc Helper function for `equal/2'. It receives two sorted `mvreg()' as parameters and can do -%% comparison directly without concerning about disorder. This is difficult to handle direclty by -%% `equal/2' without adding extra parameter, thus `eq/2' is used. -eq([], []) -> - true; -eq([H1|T1], [H2|T2]) -> - {V1, TS1} = H1, - {V2, TS2} = H2, - VEqual = V1 =:= V2, - TSEqual = riak_dt_vclock:equal(TS1, TS2), - case VEqual andalso TSEqual of - true -> - eq(T1, T2); - false -> - false - end; -eq(_, _) -> - false. - -%% @doc Return statistics of an `mvreg()'. Currently only `value_size' is returned. --spec stats(mvreg()) -> [{atom(), non_neg_integer()}]. -stats(MVReg) -> - [{value_size, stat(value_size, MVReg)}]. - --spec stat(atom(), mvreg()) -> non_neg_integer(). -stat(value_size, MVReg) -> - Values = value(MVReg), - TS = value(timestamp, MVReg), - Size = erlang:external_size(Values) + erlang:external_size(TS), - Size. - --include_lib("riak_dt/include/riak_dt_tags.hrl"). --define(DT_MVREG_TAG, 85). --define(TAG, ?DT_MVREG_TAG). + MVReg1 == MVReg2. + +-define(TAG, 85). -define(V1_VERS, 1). -%% @doc Encode an effecient binary representation of an `mvreg()' -%% Not working yet... -spec to_binary(mvreg()) -> binary(). to_binary(MVReg) -> <>. %% @doc Decode binary `mvreg()' --spec from_binary(binary()) -> {ok, mvreg()} | {error, ?UNSUPPORTED_VERSION} | ?INVALID_BINARY. +-spec from_binary(binary()) -> {ok, mvreg()} | {error, term()}. from_binary(<>) -> - {ok, riak_dt:from_binary(Bin)}; -from_binary(<>) -> - {error, ?UNSUPPORTED_VERSION(Vers)}; -from_binary(_B) -> - ?INVALID_BINARY. + {ok, riak_dt:from_binary(Bin)}. + %% @doc The following operation verifies %% that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). -is_operation(Operation) -> - case Operation of - {assign, {_, _Actor}} -> - true; - {assign, {_, Number, _Actor}} -> - (is_integer(Number) andalso (Number >= 0)); - {propagate, {_, _, _Actor}} -> - true; - _ -> - false - end. +is_operation({assign, _}) -> true; +is_operation(_) -> false. require_state_downstream(_) -> true. --spec to_binary(Vers :: pos_integer(), mvreg()) -> {ok, binary()} | -?UNSUPPORTED_VERSION. -to_binary(1, MVR) -> - {ok, to_binary(MVR)}; -to_binary(Vers, _MVR) -> - ?UNSUPPORTED_VERSION(Vers). --spec to_version(pos_integer(), mvreg()) -> mvreg(). -to_version(_Version, MVR) -> - MVR. %% =================================================================== %% EUnit tests %% =================================================================== -ifdef(TEST). -init_state() -> - [{<<>>, []}]. - -%% @doc Check if `new()' returns an empty string and an empty vector -%% clock. -new_test() -> - ?assertEqual(init_state(), new()). - -%% @doc Check if `value/1' properly returns a list of value or a list of -%% timestamp of MVReg. Checks for an empty register, a register with -%% two values and a register with only one value. -value_test() -> - Val1 = "the rain in spain falls mainly on the plane", - Val2 = "there is no rain", - VC0 = riak_dt_vclock:fresh(), - VC1 = riak_dt_vclock:increment(actor1, VC0), - VC2 = riak_dt_vclock:increment(actor2, VC0), - MVReg0 = new(), - MVReg1 = [{Val1, VC1}, {Val2, VC2}], - MVReg2 = [{Val1, VC1}], - ?assertEqual([<<>>], value(MVReg0)), - ?assertEqual(lists:sort([Val1, Val2]), lists:sort(value(MVReg1))), - ?assertEqual(lists:sort([VC1, VC2]), lists:sort(value(timestamp, MVReg1))), - ?assertEqual([Val1], value(MVReg2)), - ?assertEqual([VC1], value(timestamp, MVReg2)). - -%% @doc Check if `equal/2' works. -equal_test() -> - %% Test equal for empty MVReg - ?assert(equal(init_state(), new())), - MVReg1 = [{value1, [{actor1, 2}, {actor2, 1}]}, {value2, [{actor4, 1}, {actor3, 2}]}], - MVReg2 = [{value2, [{actor4, 1}, {actor3, 2}]}, {value1, [{actor2, 1}, {actor1, 2}]}], - %%Test if different order does not matter. - ?assert(equal(MVReg1, MVReg2)), - MVReg3 = [{value1, [{actor1, 2}, {actor2, 1}]}], - %% MVReg1 is superset of MVReg3 - ?assertNot(equal(MVReg1, MVReg3)), - MVReg4 = [{value1, [{actor1, 2}, {actor2, 1}]}, {value2, [{actor4, 1}, {actor3, 2}]}, {value3, [{actor5, 2}]}], - %% MVReg1 is subset of MVReg4 - ?assertNot(equal(MVReg1, MVReg4)), - MVReg5 = [{value0, [{actor1, 1}, {actor2, 1}]}, {value2, [{actor4, 1}, {actor3, 2}]}], - %% MVReg5 has a value different from MVReg1 - ?assertNot(equal(MVReg1, MVReg5)). - -% @doc Check if `merge/2' works. -merge_test() -> - MVReg1 = [{value1, [{actor1, 2}, {actor2, 1}]}, {value2, [{actor3, 2}, {actor4, 1}]}], - MVReg2 = [{value2, [{actor3, 2}, {actor4, 1}]}, {value1, [{actor1, 2}, {actor2, 1}]}], - MergedMVReg1 = merge(MVReg1, MVReg2), - %% Merge two MVRegs that are same should not change anything - ?assert(equal(MVReg1, MergedMVReg1)), - MVReg3 = [{value1, [{actor1, 2}, {actor2, 1}]}], - MVReg4 = [{value2, [{actor3, 2}, {actor4, 1}]}], - MergedMVReg2 = merge(MVReg3, MVReg4), - %% Merge two disjoint MVRegs should work - ?assert(equal(MVReg1, MergedMVReg2)), - MVReg5 = [{value1, [{actor1, 3}, {actor2, 1}]}, {value2, [{actor1, 2}, {actor2, 3}]}], - MVReg6 = [{value3, [{actor1, 1}, {actor2, 3}]}, {value4, [{actor1, 3}, {actor2, 2}]}], - MergedMVReg3 = merge(MVReg5, MVReg6), - %% Merge two MVRegs that have overlapping - ?assert(equal([{value2, [{actor1, 2}, {actor2, 3}]}, {value4, [{actor1, 3}, {actor2, 2}]}], MergedMVReg3)), - MVReg7 = [{value3, [{actor1, 3}, {actor2, 3}]}], - MergedMVReg4 = merge(MVReg5, MVReg7), - %% Merge two MVRegs that one dominates the other - ?assert(equal(MVReg7, MergedMVReg4)). - - -% @doc Check if `if_dominate/2' works. -if_descends_test() -> - VC1 = [[{actor1, 2}, {actor2, 3}, {actor3,2}], [{actor1,3}, {actor2,1}, {actor4,2}]], - VC2 = [{actor1, 1}], - ?assert(if_descends(VC1, VC2)), - VC3 = [{actor1, 2}, {actor3,1}], - ?assert(if_descends(VC1, VC3)), - VC4 = [{actor3, 1}, {actor4,1}], - ?assertNot(if_descends(VC1, VC4)). - -apply_update(Op, MVreg) -> - {ok, Downstream} = downstream(Op, MVreg), - update(Downstream, MVreg). - -% @doc Check if `update/3' by assign without providing timestamp works. -basic_assign_test() -> - MVReg0 = new(), - VC0 = riak_dt_vclock:fresh(), - VC1 = riak_dt_vclock:increment(actor0, VC0), - VC2 = riak_dt_vclock:increment(actor0, VC1), - {ok, MVReg1} = apply_update({assign, {value0, actor0}}, MVReg0), - ?assertEqual([{value0, VC1}], MVReg1), - {ok, MVReg2} = apply_update({assign, {value1, actor0}}, MVReg1), - ?assertEqual([{value1, VC2}], MVReg2). - -%% @doc Check if `update/3' by assign with timestamp works. -update_assign_withts_test() -> - MVReg0 = new(), - VC0 = riak_dt_vclock:fresh(), - VC1 = riak_dt_vclock:increment(actor1, VC0), - VC2 = riak_dt_vclock:increment(actor1, VC1), - VC3 = riak_dt_vclock:increment(actor1, VC2), - VC4 = riak_dt_vclock:increment(actor1, VC3), - VC5 = riak_dt_vclock:increment(actor2, VC4), - VC6 = riak_dt_vclock:increment(actor2, VC5), - %% Update a MVReg with a large timestamp. The timestmap of MVReg will be updated to given value. - {ok, MVReg1} = apply_update({assign, {value1, 2, actor1}}, MVReg0), - ?assertEqual([{value1, VC2}], MVReg1), - %% Update a MVReg with a lower timestamp than the current one; should have no effect. - {ok, MVReg2} = apply_update({assign, {value0, 1, actor1}}, MVReg1), - ?assertEqual([{value1, VC2}], MVReg2), - %% Test again with higher timestamp for actor1 - {ok, MVReg3} = apply_update({assign, {value2, 4, actor1}}, MVReg2), - ?assertEqual([{value2, VC4}], MVReg3), - %% Test with actor2 - {ok, MVReg4} = apply_update({assign, {value3, 2, actor2}}, MVReg3), - ?assertEqual([{value3, VC6}], MVReg4). - -%% @doc Update a MVReg with two different actors. Check if both actors are kept in the vector clock. -update_diff_actor_test() -> - MVR0 = new(), - VC0 = riak_dt_vclock:fresh(), - VC1 = riak_dt_vclock:increment(actor1, VC0), - VC2 = riak_dt_vclock:increment(actor2, VC1), - {ok, MVR1} = apply_update({assign, {value1, actor1}}, MVR0), - {ok, MVR2} = apply_update({assign, {value2, actor2}}, MVR1), - Value = value(MVR2), - TS = value(timestamp, MVR2), - ?assertEqual([value2], Value), - ?assertEqual([VC2], TS). - -%% @doc Check if `update/3' with propagate works. -propagate_test() -> - MVReg1_0 = new(), - VC0 = riak_dt_vclock:fresh(), - VC1 = riak_dt_vclock:increment(actor1, VC0), - VC2 = riak_dt_vclock:increment(actor2, VC0), - {ok, MVReg1_1} = apply_update({assign, {value1, actor1}}, MVReg1_0), - %% Propagate a timestamp that is not compatible with the current ones - {ok, MVRMerge1} = apply_update({propagate, {value2, VC2, nothing}}, MVReg1_1), - ?assertEqual(lists:sort([value1, value2]), lists:sort(value(MVRMerge1))), - ?assertEqual(lists:sort([VC1, VC2]), lists:sort(value(timestamp, MVRMerge1))), - VC12 = riak_dt_vclock:increment(actor2, VC1), - %% Propagate a timestamp that dominates all current ones - {ok, MVRMerge2} = apply_update({propagate, {value2, VC12, nothing}}, MVRMerge1), - ?assertEqual([value2], value(MVRMerge2)), - ?assertEqual([VC12], value(timestamp, MVRMerge2)), - %% Propagate a timestamp that is dominated by the current one - {ok, MVRMerge3} = apply_update({propagate, {value3, VC1, nothing}}, MVRMerge2), - ?assertEqual([value2], value(MVRMerge3)), - ?assertEqual([VC12], value(timestamp, MVRMerge3)). - -%% @doc Check if a diverged MVReg merges all vector clocks after being updated. -update_assign_diverge_test() -> - VC0 = riak_dt_vclock:fresh(), - VC1 = riak_dt_vclock:increment(actor1, VC0), - VC2 = riak_dt_vclock:increment(actor2, VC0), - %% This represents a MVReg that have two concurrent assignment (one propagated). - MVReg0 = [{value1, VC1}, {value2, VC2}], - {ok, MVReg1} = apply_update({assign, {value3, actor1}}, MVReg0), - VC1_2 = riak_dt_vclock:increment(actor2, VC1), - VC1_3 = riak_dt_vclock:increment(actor1, VC1_2), - %% After updating, the MVReg should only have one vector clock, - %% having the maximum count of actors from each vector clock. - %% Update with actor1 (existing) - ?assert(equal([{value3, VC1_3}], MVReg1)), - {ok, MVReg2} = apply_update({assign, {value4, actor3}}, MVReg0), - VC1_4 = riak_dt_vclock:increment(actor3, VC1_2), - %% Check when updated with actor3, which was not in MVReg - ?assert(equal([{value4, VC1_4}], MVReg2)). - -%% Do we need a merge? Anyway its functionality is very similar to propagate. -%merge_test() -> -% MVReg1 = {old_value, 3}, -% MVReg2 = {new_value, 4}, -% ?assertEqual({<<>>, 0}, merge(new(), new())), -% ?assertEqual({new_value, 4}, merge(MVReg1, MVReg2)), -% ?assertEqual({new_value, 4}, merge(MVReg2, MVReg1)). - -%% @doc Check if serialization (`to_binary/1', `from_binary/1') works. -roundtrip_bin_test() -> - MVReg = new(), - {ok, MVReg1} = apply_update({assign, {2, a1}}, MVReg), - {ok, MVReg2} = apply_update({assign, {4, a2}}, MVReg1), - {ok, MVReg3} = apply_update({assign, {89, a3}}, MVReg2), - {ok, MVReg4} = apply_update({assign, {<<"this is a binary">>, a4}}, MVReg3), - Bin = to_binary(MVReg4), - {ok, Decoded} = from_binary(Bin), - ?assert(equal(MVReg4, Decoded)). - -%% @doc Check if stas return the correct size of MVReg. -stat_test() -> - MVReg = new(), - {ok, MVReg1} = apply_update({assign, {<<"abcd">>, 1}}, MVReg), - ?assertEqual([{value_size, 25}], stats(MVReg)), - ?assertEqual([{value_size, 40}], stats(MVReg1)), - ?assertEqual(40, stat(value_size, MVReg1)). - -is_operation_test() -> - ?assertEqual(true, is_operation({assign, {value, actor}})), - ?assertEqual(true, is_operation({assign, {something, 20, actor}})), - ?assertEqual(false, is_operation({assign, {something, some_value, actor}})), - ?assertEqual(false, is_operation({add, atom})), - ?assertEqual(false, is_operation({anything, [1,2,3]})). -endif. diff --git a/test/prop_crdt_mvreg.erl b/test/prop_crdt_mvreg.erl new file mode 100644 index 000000000..ba1f524e2 --- /dev/null +++ b/test/prop_crdt_mvreg.erl @@ -0,0 +1,45 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_mvreg). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_mvreg_spec/0]). + + +prop_mvreg_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_mvreg, fun op/0, fun spec/1). + + +spec(Operations) -> + Values = + [Val || {Clock, {assign, Val}} <- Operations, + [] == [Clock2 || {Clock2, {assign, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)]], + lists:sort(Values). + + + +% generates a random counter operation +op() -> + {assign, oneof([a,b,c,d,e,f,g,h,i])}. + From 60374991c2603c70ce540076eb97b752b30b73fc Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 15:48:06 +0200 Subject: [PATCH 141/426] fixed return value for orset:from_binary --- src/antidote_crdt_orset.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 2d5a32f2a..3ed3dda8a 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -195,7 +195,7 @@ to_binary(ORSet) -> from_binary(<>) -> %% @TODO something smarter - binary_to_term(Bin). + {ok, binary_to_term(Bin)}. %% Private %% @doc add an element and its token to the `orset()'. From d127246986d4ddb15fdb4263441ae0f990ae422a Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 16:10:40 +0200 Subject: [PATCH 142/426] gset fix --- src/antidote_crdt_gset.erl | 6 +++--- test/prop_crdt_gset.erl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/antidote_crdt_gset.erl b/src/antidote_crdt_gset.erl index 22db59094..38b0f9c6f 100644 --- a/src/antidote_crdt_gset.erl +++ b/src/antidote_crdt_gset.erl @@ -54,12 +54,12 @@ value(Set) -> -spec downstream(gset_op(), gset()) -> {ok, gset_effect()}. downstream({add, Elem}, _State) -> - ordsets:from_list([Elem]); + {ok, ordsets:from_list([Elem])}; downstream({add_all, Elems}, _State) -> - ordsets:from_list(Elems). + {ok, ordsets:from_list(Elems)}. update(Effect, State) -> - ordsets:union(State, Effect). + {ok, ordsets:union(State, Effect)}. require_state_downstream(_Operation) -> false. diff --git a/test/prop_crdt_gset.erl b/test/prop_crdt_gset.erl index 76131b87f..ac50d6929 100644 --- a/test/prop_crdt_gset.erl +++ b/test/prop_crdt_gset.erl @@ -28,7 +28,7 @@ prop_gset_spec() -> - crdt_properties:crdt_satisfies_spec(antidote_crdt_orset, fun set_op/0, fun add_wins_set_spec/1). + crdt_properties:crdt_satisfies_spec(antidote_crdt_gset, fun set_op/0, fun add_wins_set_spec/1). add_wins_set_spec(Operations) -> From d49080512b9b8040b87c2001ed17c37c1a11f3e1 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 16:16:08 +0200 Subject: [PATCH 143/426] added add_all and remove_all to test --- test/prop_crdt_orset.erl | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/prop_crdt_orset.erl b/test/prop_crdt_orset.erl index 9c11a47ec..e64b1cca2 100644 --- a/test/prop_crdt_orset.erl +++ b/test/prop_crdt_orset.erl @@ -31,7 +31,8 @@ prop_orset_spec() -> crdt_properties:crdt_satisfies_spec(antidote_crdt_orset, fun set_op/0, fun add_wins_set_spec/1). -add_wins_set_spec(Operations) -> +add_wins_set_spec(Operations1) -> + Operations = lists:flatmap(fun normalizeOperation/1, Operations1), lists:usort( % all X, [X || @@ -41,12 +42,23 @@ add_wins_set_spec(Operations) -> [] == [Y || {RemoveClock, {remove, Y}} <- Operations, X == Y, crdt_properties:clock_le(AddClock, RemoveClock)] ]). +% transforms add_all and remove_all into single operations +normalizeOperation({Clock, {add_all, Elems}}) -> + [{Clock, {add, Elem}} || Elem <- Elems]; +normalizeOperation({Clock, {remove_all, Elems}}) -> + [{Clock, {remove, Elem}} || Elem <- Elems]; +normalizeOperation(X) -> + [X]. + % generates a random counter operation set_op() -> oneof([ {add, set_element()}, - {remove, set_element()} + {add_all, list(set_element())}, + {remove, set_element()}, + {remove_all, list(set_element())} ]). set_element() -> - oneof([a,b]). \ No newline at end of file + oneof([a,b]). + From 6bab481c3a116518ccec9514050d5c127f7e329c Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 30 Sep 2016 17:19:40 +0200 Subject: [PATCH 144/426] started to integrate Mathias' map from: https://github.com/mweberUKL/antidote/blob/a1a6d177297489bf09865f35f1e3ebc506fc7cec/src/crdt_map.erl still needs more tests --- src/antidote_crdt_gmap.erl | 137 +++++++++++++++++++++++++++++++++++++ test/crdt_properties.erl | 8 ++- test/prop_crdt_counter.erl | 2 +- test/prop_crdt_gmap.erl | 66 ++++++++++++++++++ test/prop_crdt_orset.erl | 2 +- 5 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 src/antidote_crdt_gmap.erl create mode 100644 test/prop_crdt_gmap.erl diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl new file mode 100644 index 000000000..a5bb3fb78 --- /dev/null +++ b/src/antidote_crdt_gmap.erl @@ -0,0 +1,137 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc module antidote_crdt_gmap - A grow-only map +%% +%% This map simply forwards all operations to the embedded CRDTs. +%% There is no real remove-operation. +%% + +-module(antidote_crdt_gmap). + +-behaviour(antidote_crdt). + +%% API +-export([new/0, value/1, update/2, equal/2, + to_binary/1, from_binary/1, is_operation/1, downstream/2, require_state_downstream/1]). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + +-type gmap() :: dict:dict(). +-type gmap_op() :: + {update, nested_op()} + | {update, [nested_op()]}. +-type nested_op() :: {{Key::term(), Type::atom }, Op::term()}. +-type gmap_effect() :: + {update, nested_downstream()} + | {update, [nested_downstream()]}. +-type nested_downstream() :: {{Key::term(), Type::atom }, Op::term()}. + +-spec new() -> gmap(). +new() -> + dict:new(). + +-spec value(gmap()) -> dict:dict(). +value(Map) -> + lists:sort([{{Key,Type}, Type:value(Value)} || {{Key, Type}, Value} <- dict:to_list(Map)]). + +-spec require_state_downstream(gmap_op()) -> boolean(). +require_state_downstream(_Op) -> + true. + + +-spec downstream(gmap_op(), gmap()) -> {ok, gmap_effect()}. +downstream({update, {{Key, Type}, Op}}, CurrentMap) -> + % TODO could be optimized for some types + CurrentValue = case dict:is_key({Key, Type}, CurrentMap) of + true -> dict:fetch({Key, Type}, CurrentMap); + false -> Type:new() + end, + {ok, DownstreamOp} = Type:downstream(Op, CurrentValue), + {ok, {update, {{Key, Type}, DownstreamOp}}}; +downstream({update, Ops}, CurrentMap) when is_list(Ops) -> + {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}. + +-spec update(gmap_effect(), gmap()) -> {ok, gmap()}. +update({update, {{Key, Type}, Op}}, Map) -> + case dict:is_key({Key, Type}, Map) of + true -> {ok, dict:update({Key, Type}, fun(V) -> {ok, Value} = Type:update(Op, V), Value end, Map)}; + false -> NewValue = Type:new(), + {ok, NewValueUpdated} = Type:update(Op, NewValue), + {ok, dict:store({Key, Type}, NewValueUpdated, Map)} + end; +update({update, Ops}, Map) -> + apply_ops(Ops, Map). + +apply_ops([], Map) -> + {ok, Map}; +apply_ops([Op | Rest], Map) -> + {ok, ORDict1} = update(Op, Map), + apply_ops(Rest, ORDict1). + + + +equal(Map1, Map2) -> + Map1 == Map2. % TODO better implementation (recursive equals) + + +-define(TAG, 101). +-define(V1_VERS, 1). + +to_binary(Policy) -> + %% @TODO something smarter + <>. + +from_binary(<>) -> + %% @TODO something smarter + {ok, binary_to_term(Bin)}. + +is_operation(Operation) -> + case Operation of + {update, {{_Key, Type}, _Op}} -> + antidote_crdt:is_type(Type); + {update, Ops} when is_list(Ops) -> + lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); + _ -> + false + end. + + +%% =================================================================== +%% EUnit tests +%% =================================================================== +% TODO +-ifdef(TEST). +new_test() -> + ?assertEqual(dict:new(), new()). + +update_test() -> + Map1 = new(), + {ok, DownstreamOp} = downstream({update, {{key1, crdt_lwwreg}, {assign, <<"test">>}}}, Map1), + ?assertMatch({update, {{key1, crdt_lwwreg}, {assign, <<"test">>, _TS}}}, DownstreamOp), + {ok, Map2} = update(DownstreamOp, Map1), + Key1Value = dict:fetch({key1, crdt_lwwreg}, value(Map2)), + ?assertEqual(<<"test">>, Key1Value). +-endif. + + diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl index c0a4617d4..1dee6515b 100644 --- a/test/crdt_properties.erl +++ b/test/crdt_properties.erl @@ -52,7 +52,7 @@ %% Crdt: module name of the CRDT to test %% OperationGen: proper generator for generating a single random CRDT operation %% Spec: A function which takes a list of {Clock,Operation} pairs. The clock can be used to determine the happens-before relation between operations --spec crdt_satisfies_spec(atom(), fun(() -> proper_types:raw_type()), fun(([clocked_operation()]) -> boolean())) -> proper:forall_clause(). +-spec crdt_satisfies_spec(atom(), fun(() -> proper_types:raw_type()), fun(([clocked_operation()]) -> term())) -> proper:forall_clause(). crdt_satisfies_spec(Crdt, OperationGen, Spec) -> ?FORALL(Ops, generateOps(OperationGen), checkSpec(Crdt, Ops, Spec) @@ -77,6 +77,12 @@ clock_le(A, B) -> % executes/checks the specification checkSpec(Crdt, Ops, Spec) -> + % check that all generated operatiosn are valid: + _ = [case Crdt:is_operation(Op) of + true -> true; + false -> throw({invalid_operation, Op}) + end || {exec, _, Op} <- Ops], + InitialState = maps:from_list( [{Dc, #test_replica_state{state = Crdt:new()}} || Dc <- [dc1, dc2, dc3]]), EndState = execSystem(Crdt, Ops, InitialState), diff --git a/test/prop_crdt_counter.erl b/test/prop_crdt_counter.erl index fb950f0bf..fae2c8409 100644 --- a/test/prop_crdt_counter.erl +++ b/test/prop_crdt_counter.erl @@ -24,7 +24,7 @@ -include_lib("proper/include/proper.hrl"). %% API --export([prop_counter_spec/0]). +-export([prop_counter_spec/0, counter_op/0, counter_spec/1]). prop_counter_spec() -> diff --git a/test/prop_crdt_gmap.erl b/test/prop_crdt_gmap.erl new file mode 100644 index 000000000..d3bff3865 --- /dev/null +++ b/test/prop_crdt_gmap.erl @@ -0,0 +1,66 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_gmap). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_gmap_spec/0]). + + +prop_gmap_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_gmap, fun op/0, fun spec/1). + + +spec(Operations1) -> + Operations = lists:flatmap(fun normalizeOp/1, Operations1), + Keys = lists:usort([Key || {_, {update, {Key, _}}} <- Operations]), + GroupedByKey = [{Key, [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2 ]} || Key <- Keys], + NestedSpec = [{{Key,Type}, nestedSpec(Type, Ops)} || {{Key,Type}, Ops} <- GroupedByKey], + lists:sort(NestedSpec). + +nestedSpec(antidote_crdt_gmap, Ops) -> spec(Ops); +nestedSpec(antidote_crdt_counter, Ops) -> prop_crdt_counter:counter_spec(Ops). + + +normalizeOp({Clock, {update, List}}) when is_list(List) -> + [{Clock, {update, X}} || X <- List]; +normalizeOp(X) -> [X]. + + +% generates a random counter operation +op() -> + {update, oneof([nestedOp(), list(nestedOp())])}. + +nestedOp() -> + oneof([ +%% {{key(), antidote_crdt_gmap}, op()}, + % TODO add other type (orset) and recursive maps + {{key(), antidote_crdt_counter}, prop_crdt_counter:counter_op()} + ]). + + +key() -> + oneof([a,b,c,d]). + + + diff --git a/test/prop_crdt_orset.erl b/test/prop_crdt_orset.erl index e64b1cca2..388d07d05 100644 --- a/test/prop_crdt_orset.erl +++ b/test/prop_crdt_orset.erl @@ -24,7 +24,7 @@ -include_lib("proper/include/proper.hrl"). %% API --export([prop_orset_spec/0]). +-export([prop_orset_spec/0, set_op/0, add_wins_set_spec/1]). prop_orset_spec() -> From f1ace3db5ed71995e37fc528dc2dd3e716d0cb6a Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Sat, 1 Oct 2016 19:07:17 +0200 Subject: [PATCH 145/426] fixed lwwreg operation check --- src/antidote_crdt_lwwreg.erl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/antidote_crdt_lwwreg.erl b/src/antidote_crdt_lwwreg.erl index 267e616fc..8cfdc1e06 100644 --- a/src/antidote_crdt_lwwreg.erl +++ b/src/antidote_crdt_lwwreg.erl @@ -74,6 +74,7 @@ update(Effect, State) -> require_state_downstream(_Operation) -> true. is_operation({assign, _Value}) -> true; +is_operation({assign, _Value, _Time}) -> true; is_operation(_Other) -> false. From 15cc2fa961dc1f947139ac56dfeec97b77aab4ce Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Sat, 1 Oct 2016 19:09:23 +0200 Subject: [PATCH 146/426] allow empty lists in add_all operation --- src/antidote_crdt_orset.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 3ed3dda8a..86910e512 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -245,10 +245,10 @@ minimum_tokens(Tokens) -> %% @doc The following operation verifies %% that Operation is supported by this particular CRDT. is_operation({add, _Elem}) -> true; -is_operation({add_all, [_H|_T]}) -> true; +is_operation({add_all, L}) when is_list(L) -> true; is_operation({remove, _Elem}) -> true; -is_operation({remove_all, [_H|_T]}) -> true; +is_operation({remove_all, L}) when is_list(L) -> true; is_operation(_) -> false. require_state_downstream({add,_}) -> From c4273fc36672015c819d4d7a328342aa95521d7f Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Sat, 1 Oct 2016 22:42:47 +0200 Subject: [PATCH 147/426] fixed map, did not work with nested ops and multiple keys in a list of updates --- src/antidote_crdt.erl | 3 ++- src/antidote_crdt_gmap.erl | 22 ++++++++++++------- test/crdt_properties.erl | 14 +++++++++++-- test/prop_crdt_gmap.erl | 43 +++++++++++++++++++++++++++++--------- 4 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index beef83b4d..781df577c 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -31,7 +31,8 @@ antidote_crdt_rga, antidote_crdt_bcounter, antidote_crdt_mvreg, - antidote_crdt_map + antidote_crdt_map, + antidote_crdt_gmap ]). -export([is_type/1 diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index a5bb3fb78..064fc7dff 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -107,14 +107,20 @@ from_binary(<>) -> {ok, binary_to_term(Bin)}. is_operation(Operation) -> - case Operation of - {update, {{_Key, Type}, _Op}} -> - antidote_crdt:is_type(Type); - {update, Ops} when is_list(Ops) -> - lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); - _ -> - false - end. + case Operation of + {update, {{_Key, Type}, Op}} -> + antidote_crdt:is_type(Type) + andalso Type:is_operation(Op); + {update, Ops} when is_list(Ops) -> + distinct([Key || {Key, _} <- Ops]) + andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); + _ -> + false + end. + +distinct([]) -> true; +distinct([X|Xs]) -> + not lists:member(X, Xs) andalso distinct(Xs). %% =================================================================== diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl index 1dee6515b..98acaea61 100644 --- a/test/crdt_properties.erl +++ b/test/crdt_properties.erl @@ -86,7 +86,10 @@ checkSpec(Crdt, Ops, Spec) -> InitialState = maps:from_list( [{Dc, #test_replica_state{state = Crdt:new()}} || Dc <- [dc1, dc2, dc3]]), EndState = execSystem(Crdt, Ops, InitialState), - lists:all(fun(R) -> checkSpecEnd(Crdt, Spec, EndState, R) end, maps:keys(EndState)). + conjunction( + [{R, + checkSpecEnd(Crdt, Spec, EndState, R)} + || R <- maps:keys(EndState)]). checkSpecEnd(Crdt, Spec, EndState, R) -> RState = maps:get(R, EndState), @@ -100,7 +103,14 @@ checkSpecEnd(Crdt, Spec, EndState, R) -> clock_le(Clock, RClock)], SpecValue = Spec(VisibleOperations), - SpecValue == RValue. + ?WHENFAIL( + begin + io:format("Reading value on ~p~n", [R]), + io:format("Expected value: ~p~n", [SpecValue]), + io:format("Actual value : ~p~n", [RValue]) + end, + SpecValue == RValue + ). -spec execSystem(atom(), [test_operation()], test_state()) -> test_state(). diff --git a/test/prop_crdt_gmap.erl b/test/prop_crdt_gmap.erl index d3bff3865..1c9a61a01 100644 --- a/test/prop_crdt_gmap.erl +++ b/test/prop_crdt_gmap.erl @@ -39,6 +39,7 @@ spec(Operations1) -> lists:sort(NestedSpec). nestedSpec(antidote_crdt_gmap, Ops) -> spec(Ops); +nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); nestedSpec(antidote_crdt_counter, Ops) -> prop_crdt_counter:counter_spec(Ops). @@ -47,16 +48,36 @@ normalizeOp({Clock, {update, List}}) when is_list(List) -> normalizeOp(X) -> [X]. -% generates a random counter operation -op() -> - {update, oneof([nestedOp(), list(nestedOp())])}. - -nestedOp() -> - oneof([ -%% {{key(), antidote_crdt_gmap}, op()}, - % TODO add other type (orset) and recursive maps - {{key(), antidote_crdt_counter}, prop_crdt_counter:counter_op()} - ]). +% generates a random operation +op() -> ?SIZED(Size, op(Size)). +op(Size) -> + {update, oneof([ + nestedOp(Size), + ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, [])) + ])}. + +removeDuplicateKeys([], _) -> []; +removeDuplicateKeys([{Key,Op}|Rest], Keys) -> + case lists:member(Key, Keys) of + true -> removeDuplicateKeys(Rest, Keys); + false -> [{Key, Op}|removeDuplicateKeys(Rest, [Key|Keys])] + end. + +nestedOp(Size) -> + oneof( + [ + % TODO add other type (orset) and recursive maps + % TODO make sure that keys are unique here and in the is_operation check + {{key(), antidote_crdt_orset}, prop_crdt_orset:set_op()}, + {{key(), antidote_crdt_counter}, prop_crdt_counter:counter_op()} + ] + ++ + if + Size > 1 -> + [{{key(), antidote_crdt_gmap}, ?LAZY(op(Size div 2))}]; + true -> [] + end + ). key() -> @@ -64,3 +85,5 @@ key() -> + + From 7edc6ef4581a0f3f0aa680e213deaeb187a1996a Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 3 Oct 2016 19:06:30 +0200 Subject: [PATCH 148/426] fixed gmap:value type --- src/antidote_crdt_gmap.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index 064fc7dff..3ed14f7b9 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -51,7 +51,7 @@ new() -> dict:new(). --spec value(gmap()) -> dict:dict(). +-spec value(gmap()) -> [{{Key::term(), Type::atom}, Value::term()}]. value(Map) -> lists:sort([{{Key,Type}, Type:value(Value)} || {{Key, Type}, Value} <- dict:to_list(Map)]). From f170229a8f6af824517c02be341455a223a54f78 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 3 Oct 2016 19:51:25 +0200 Subject: [PATCH 149/426] added other operations to counter test --- test/prop_crdt_counter.erl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/prop_crdt_counter.erl b/test/prop_crdt_counter.erl index fae2c8409..39a56aed5 100644 --- a/test/prop_crdt_counter.erl +++ b/test/prop_crdt_counter.erl @@ -32,9 +32,17 @@ prop_counter_spec() -> counter_spec(Operations) -> - lists:sum([X || {_, {increment, X}} <- Operations]) - lists:sum([X || {_, {decrement, X}} <- Operations]). + lists:sum([X || {_, {increment, X}} <- Operations]) + + lists:sum([1 || {_, increment} <- Operations]) + - lists:sum([X || {_, {decrement, X}} <- Operations]) + - lists:sum([1 || {_, decrement} <- Operations]). % generates a random counter operation counter_op() -> - tuple([oneof([increment, decrement]), non_neg_integer()]). + oneof([ + increment, + decrement, + {increment, integer()}, + {decrement, integer()} + ]). From b024fdfcaa9944be3ad1879f2373741ef0319672 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 3 Oct 2016 19:51:43 +0200 Subject: [PATCH 150/426] operation based integer (counter with set-operation) --- src/antidote_crdt_integer.erl | 173 ++++++++++++++++++++++++++++++++++ test/prop_crdt_integer.erl | 56 +++++++++++ 2 files changed, 229 insertions(+) create mode 100644 src/antidote_crdt_integer.erl create mode 100644 test/prop_crdt_integer.erl diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl new file mode 100644 index 000000000..20da9c785 --- /dev/null +++ b/src/antidote_crdt_integer.erl @@ -0,0 +1,173 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% antidote_crdt_integer: A convergent, replicated, operation +%% based integer +%% +%% + +-module(antidote_crdt_integer). + +-behaviour(antidote_crdt). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + +-type state() :: {[{term(), integer()}], integer()}. +-type update() :: + {increment, integer()} + | {set, integer()}. +-type effect() :: + {increment, integer()} + | {set, term(), [term()], integer()}. +-type value() :: integer(). + + +-spec new() -> state(). +new() -> + {[{initial, 0}], 0}. + +-spec value(state()) -> value(). +value({Vals, Delta}) -> + lists:max([X || {_,X} <- Vals]) + Delta. + +-spec downstream(update(), state()) -> {ok, effect()}. +downstream({increment, N}, _State) -> + {ok, {increment, N}}; +downstream({set, N}, {Vals, Delta}) -> + Overridden = [Tag || {Tag, _} <- Vals], + {ok, {set, unique(), Overridden, N-Delta}}. + +unique() -> + crypto:strong_rand_bytes(20). + +%% @doc Update a `pncounter()'. The first argument is either the atom +%% `increment' or `decrement' or the two tuples `{increment, pos_integer()}' or +%% `{decrement, pos_integer()}'. +%% In the case of the former, the operation's amount +%% is `1'. Otherwise it is the value provided in the tuple's second element. +%% The 2nd argument is the `pncounter()' to update. +%% +%% returns the updated `pncounter()' +-spec update(effect(), state()) -> {ok, state()}. +update({set, Token, Overridden, N}, {Vals, Delta}) -> + Surviving = [{T,V} || {T,V} <- Vals, not lists:member(T, Overridden)], + {ok, {[{Token, N}|Surviving], Delta}}; +update({increment, N}, {Vals, Delta}) -> + {ok, {Vals, Delta + N}}. + +%% @doc Compare if two `pncounter()' are equal. Only returns `true()' if both +%% of their positive and negative entries are equal. +-spec equal(state(), state()) -> boolean(). +equal(PNCnt1, PNCnt2) -> + PNCnt1 =:= PNCnt2. + +-spec to_binary(state()) -> binary(). +to_binary(PNCounter) -> + term_to_binary(PNCounter). + +from_binary(Bin) -> + %% @TODO something smarter + {ok, binary_to_term(Bin)}. + +%% @doc The following operation verifies +%% that Operation is supported by this particular CRDT. +-spec is_operation(term()) -> boolean(). +is_operation({increment, N}) when is_integer(N) -> true; +is_operation({set, N}) when is_integer(N) -> true; +is_operation(_) -> false. + +%% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt +%% to generate downstream effect +require_state_downstream(_) -> + false. + + + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). + +new_test() -> + ?assertEqual(0, new()). + +%% @doc test the correctness of `value()' function +value_test() -> + PNCnt = 4, + ?assertEqual(4, value(PNCnt)). + +%% @doc test the correctness of increment without parameter. +update_increment_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 1}, PNCnt0), + {ok, PNCnt2} = update({increment, 2}, PNCnt1), + {ok, PNCnt3} = update({increment, 1}, PNCnt2), + ?assertEqual(4, value(PNCnt3)). + +%% @doc test the correctness of increment by some numbers. +update_increment_by_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 7}, PNCnt0), + ?assertEqual(7, value(PNCnt1)). + +%% @doc test the correctness of decrement. +update_decrement_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, 1}, PNCnt0), + {ok, PNCnt2} = update({increment, 2}, PNCnt1), + {ok, PNCnt3} = update({increment, 1}, PNCnt2), + {ok, PNCnt4} = update({decrement, 1}, PNCnt3), + ?assertEqual(3, value(PNCnt4)). + +update_negative_params_test() -> + PNCnt0 = new(), + {ok, PNCnt1} = update({increment, -7}, PNCnt0), + {ok, PNCnt2} = update({decrement, -5}, PNCnt1), + ?assertEqual(-2, value(PNCnt2)). + +equal_test() -> + PNCnt1 = 4, + PNCnt2 = 2, + PNCnt3 = 2, + ?assertNot(equal(PNCnt1, PNCnt2)), + ?assert(equal(PNCnt2, PNCnt3)). + +binary_test() -> + PNCnt1 = 4, + BinaryPNCnt1 = to_binary(PNCnt1), + {ok, PNCnt2} = from_binary(BinaryPNCnt1), + ?assert(equal(PNCnt1, PNCnt2)). + +-endif. + + diff --git a/test/prop_crdt_integer.erl b/test/prop_crdt_integer.erl new file mode 100644 index 000000000..186a7f6bb --- /dev/null +++ b/test/prop_crdt_integer.erl @@ -0,0 +1,56 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_integer). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_counter_spec/0, op/0, spec/1]). + + +prop_counter_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_integer, fun op/0, fun spec/1). + + +spec(Operations) -> + ConcurrentValues = + [{Clock, Val} || {Clock, {set, Val}} <- Operations, + [] == [Clock2 || {Clock2, {set, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)]], + ConcurrentValues2 = + case ConcurrentValues of + [] -> [{#{}, 0}]; + _ -> ConcurrentValues + end, + Delta = + fun(Clock) -> + lists:sum([X || {C, {increment, X}} <- Operations, not crdt_properties:clock_le(C, Clock)]) + end, + WithDelta = [Val + Delta(Clock) || {Clock,Val} <- ConcurrentValues2], + lists:max(WithDelta). + +% generates a random counter operation +op() -> + oneof([ + {set, integer()}, + {increment, integer()} + ]). + From c755536dc40833c05cfe62b0b7e81d52099a8a80 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 3 Oct 2016 20:18:11 +0200 Subject: [PATCH 151/426] fixed eunit tests --- src/antidote_crdt_gmap.erl | 7 +++-- src/antidote_crdt_integer.erl | 50 ----------------------------------- src/antidote_crdt_orset.erl | 4 +-- 3 files changed, 5 insertions(+), 56 deletions(-) diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index 3ed14f7b9..069530ec4 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -133,11 +133,10 @@ new_test() -> update_test() -> Map1 = new(), - {ok, DownstreamOp} = downstream({update, {{key1, crdt_lwwreg}, {assign, <<"test">>}}}, Map1), - ?assertMatch({update, {{key1, crdt_lwwreg}, {assign, <<"test">>, _TS}}}, DownstreamOp), + {ok, DownstreamOp} = downstream({update, {{key1, antidote_crdt_lwwreg}, {assign, <<"test">>}}}, Map1), + ?assertMatch({update, {{key1, antidote_crdt_lwwreg}, {_TS, <<"test">>}}}, DownstreamOp), {ok, Map2} = update(DownstreamOp, Map1), - Key1Value = dict:fetch({key1, crdt_lwwreg}, value(Map2)), - ?assertEqual(<<"test">>, Key1Value). + ?assertEqual([{{key1, antidote_crdt_lwwreg}, <<"test">>}], value(Map2)). -endif. diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl index 20da9c785..3c88fa675 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/antidote_crdt_integer.erl @@ -118,56 +118,6 @@ require_state_downstream(_) -> %% =================================================================== -ifdef(TEST). -new_test() -> - ?assertEqual(0, new()). - -%% @doc test the correctness of `value()' function -value_test() -> - PNCnt = 4, - ?assertEqual(4, value(PNCnt)). - -%% @doc test the correctness of increment without parameter. -update_increment_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 1}, PNCnt0), - {ok, PNCnt2} = update({increment, 2}, PNCnt1), - {ok, PNCnt3} = update({increment, 1}, PNCnt2), - ?assertEqual(4, value(PNCnt3)). - -%% @doc test the correctness of increment by some numbers. -update_increment_by_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 7}, PNCnt0), - ?assertEqual(7, value(PNCnt1)). - -%% @doc test the correctness of decrement. -update_decrement_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({increment, 1}, PNCnt0), - {ok, PNCnt2} = update({increment, 2}, PNCnt1), - {ok, PNCnt3} = update({increment, 1}, PNCnt2), - {ok, PNCnt4} = update({decrement, 1}, PNCnt3), - ?assertEqual(3, value(PNCnt4)). - -update_negative_params_test() -> - PNCnt0 = new(), - {ok, PNCnt1} = update({increment, -7}, PNCnt0), - {ok, PNCnt2} = update({decrement, -5}, PNCnt1), - ?assertEqual(-2, value(PNCnt2)). - -equal_test() -> - PNCnt1 = 4, - PNCnt2 = 2, - PNCnt3 = 2, - ?assertNot(equal(PNCnt1, PNCnt2)), - ?assert(equal(PNCnt2, PNCnt3)). - -binary_test() -> - PNCnt1 = 4, - BinaryPNCnt1 = to_binary(PNCnt1), - {ok, PNCnt2} = from_binary(BinaryPNCnt1), - ?assert(equal(PNCnt1, PNCnt2)). - -endif. diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 86910e512..684c025b7 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -367,13 +367,13 @@ concurrent_add_test() -> binary_test() -> ORSet1 = new(), BinaryORSet1 = to_binary(ORSet1), - ORSet2 = from_binary(BinaryORSet1), + {ok, ORSet2} = from_binary(BinaryORSet1), ?assert(equal(ORSet1, ORSet2)), {ok, Op1} = downstream({add, <<"foo">>}, ORSet1), {ok, ORSet3} = update(Op1, ORSet1), BinaryORSet3 = to_binary(ORSet3), - ORSet4 = from_binary(BinaryORSet3), + {ok, ORSet4} = from_binary(BinaryORSet3), ?assert(equal(ORSet3, ORSet4)). -endif. From 6fb2d589862a799a2cdc85b2f989f715f0073556 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 3 Oct 2016 20:21:02 +0200 Subject: [PATCH 152/426] proper tests use require_state_downstream now --- src/antidote_crdt_integer.erl | 6 +++--- test/crdt_properties.erl | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl index 3c88fa675..6d862d025 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/antidote_crdt_integer.erl @@ -107,9 +107,9 @@ is_operation({set, N}) when is_integer(N) -> true; is_operation(_) -> false. %% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt -%% to generate downstream effect -require_state_downstream(_) -> - false. +%% to generate downstream effect +require_state_downstream({set,_}) -> true; +require_state_downstream(_) -> false. diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl index 98acaea61..dfedf0f30 100644 --- a/test/crdt_properties.erl +++ b/test/crdt_properties.erl @@ -144,7 +144,12 @@ execSystem(Crdt, [{pull, Source, Target}|RemainingOps], State) -> execSystem(Crdt, [{exec, Replica, Op}|RemainingOps], State) -> ReplicaState = maps:get(Replica, State), CrdtState = ReplicaState#test_replica_state.state, - {ok, Effect} = Crdt:downstream(Op, CrdtState), + CrdtStateForDownstream = + case Crdt:require_state_downstream(Op) of + true -> CrdtState; + false -> no_state + end, + {ok, Effect} = Crdt:downstream(Op, CrdtStateForDownstream), {ok, NewCrdtState} = Crdt:update(Effect, CrdtState), ReplicaClock = ReplicaState#test_replica_state.clock, From 7cc1a7ca775c8a4fbbee196be5064fdd83e451d7 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 3 Oct 2016 20:32:14 +0200 Subject: [PATCH 153/426] added proper test for binary-encoding --- src/antidote_crdt_gset.erl | 2 +- src/antidote_crdt_lwwreg.erl | 2 +- test/crdt_properties.erl | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/antidote_crdt_gset.erl b/src/antidote_crdt_gset.erl index 38b0f9c6f..dad3df6e2 100644 --- a/src/antidote_crdt_gset.erl +++ b/src/antidote_crdt_gset.erl @@ -74,7 +74,7 @@ to_binary(CRDT) -> erlang:term_to_binary(CRDT). from_binary(Bin) -> - erlang:binary_to_term(Bin). + {ok, erlang:binary_to_term(Bin)}. -ifdef(test). all_test() -> diff --git a/src/antidote_crdt_lwwreg.erl b/src/antidote_crdt_lwwreg.erl index 8cfdc1e06..82ab318e7 100644 --- a/src/antidote_crdt_lwwreg.erl +++ b/src/antidote_crdt_lwwreg.erl @@ -85,7 +85,7 @@ to_binary(CRDT) -> erlang:term_to_binary(CRDT). from_binary(Bin) -> - erlang:binary_to_term(Bin). + {ok, erlang:binary_to_term(Bin)}. -ifdef(test). all_test() -> diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl index dfedf0f30..04f9bd98f 100644 --- a/test/crdt_properties.erl +++ b/test/crdt_properties.erl @@ -87,6 +87,7 @@ checkSpec(Crdt, Ops, Spec) -> [{Dc, #test_replica_state{state = Crdt:new()}} || Dc <- [dc1, dc2, dc3]]), EndState = execSystem(Crdt, Ops, InitialState), conjunction( + [{binary_encoding, checkBinaryEncoding(Crdt, EndState)}] ++ [{R, checkSpecEnd(Crdt, Spec, EndState, R)} || R <- maps:keys(EndState)]). @@ -164,3 +165,31 @@ execSystem(Crdt, [{exec, Replica, Op}|RemainingOps], State) -> NewState = State#{Replica => NewReplicaState}, execSystem(Crdt, RemainingOps, NewState). + + +checkBinaryEncoding(Crdt, EndState) -> + conjunction([{R, checkBinaryEncoding(Crdt, EndState, R)} || R <- maps:keys(EndState)]). + +checkBinaryEncoding(Crdt, EndState, R) -> + RState = maps:get(R, EndState), + CrdtState = RState#test_replica_state.state, + BinState = Crdt:to_binary(CrdtState), + true = is_binary(BinState), + {ok, CrdtState2} = Crdt:from_binary(BinState), + + conjunction([ + {equal_state, ?WHENFAIL( + begin + io:format("CRDT state before: ~p~n", [CrdtState]), + io:format("CRDT state after: ~p~n", [CrdtState2]) + end, + Crdt:equal(CrdtState, CrdtState2) + )}, + {equal_value, ?WHENFAIL( + begin + io:format("CRDT value before: ~p~n", [Crdt:value(CrdtState)]), + io:format("CRDT value after: ~p~n", [rdt:value(CrdtState2)]) + end, + Crdt:value(CrdtState) == Crdt:value(CrdtState2) + )} + ]). \ No newline at end of file From c22be1afe05f89f61324118a5159f86a459ac82e Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Tue, 4 Oct 2016 00:39:41 +0200 Subject: [PATCH 154/426] added remove-wins set --- src/antidote_crdt.erl | 3 +- src/antidote_crdt_set_rw.erl | 149 +++++++++++++++++++++++++++++++++++ test/prop_crdt_set_rw.erl | 65 +++++++++++++++ 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/antidote_crdt_set_rw.erl create mode 100644 test/prop_crdt_set_rw.erl diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 781df577c..961e41a0e 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -32,7 +32,8 @@ antidote_crdt_bcounter, antidote_crdt_mvreg, antidote_crdt_map, - antidote_crdt_gmap + antidote_crdt_gmap, + antidote_crdt_set_rw ]). -export([is_type/1 diff --git a/src/antidote_crdt_set_rw.erl b/src/antidote_crdt_set_rw.erl new file mode 100644 index 000000000..d4a52bab1 --- /dev/null +++ b/src/antidote_crdt_set_rw.erl @@ -0,0 +1,149 @@ +%% ------------------------------------------------------------------- +%% +%% crdt_set: A convergent, replicated, operation based observe remove set +%% +%% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc +%% An operation-based Remove-wins Set CRDT. +%% +%% @end +-module(antidote_crdt_set_rw). + + +%% Callbacks +-export([ new/0, + value/1, + downstream/2, + update/2, + equal/2, + to_binary/1, + from_binary/1, + is_operation/1, + require_state_downstream/1 + ]). + + +-behaviour(antidote_crdt). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-export_type([set/0, binary_set/0, set_op/0]). +-opaque set() :: orddict:orddict(term(), [token()]). + +-type binary_set() :: binary(). %% A binary that from_binary/1 will operate on. + +-type set_op() :: {add, member()} | {remove, member()} | + {add_all, [member()]} | {remove_all, [member()]}. + +-type token() :: term(). +-type effect() :: + {add, [{member(), [token()]}]} + | {remove, [{member(), [token()]}], token()}. + +-type member() :: term(). + +-spec new() -> set(). +new() -> + orddict:new(). + +-spec value(set()) -> [member()]. +value(Dict) -> + [Val || {Val, []} <- orddict:to_list(Dict)]. + + +-spec downstream(set_op(), set()) -> {ok, effect()}. +downstream({add, Elem}, Dict) -> + downstream({add_all, [Elem]}, Dict); +downstream({add_all,Elems}, Dict) -> + {ok, {add, elemsWithRemovedTombstones(lists:usort(Elems), Dict)}}; +downstream({remove, Elem}, Dict) -> + downstream({remove_all, [Elem]}, Dict); +downstream({remove_all, Elems}, Dict) -> +%% {ok, {remove, [{E,[]} || E <- lists:usort(Elems)], unique()}}. +% TODO optimization: + {ok, {remove, elemsWithRemovedTombstones(lists:usort(Elems), Dict), unique()}}. + +%% @doc generate a unique identifier (best-effort). +unique() -> + crypto:strong_rand_bytes(20). + +elemsWithRemovedTombstones([], _Dict) -> []; +elemsWithRemovedTombstones(Elems, []) -> [{E,[]} || E <- Elems]; +elemsWithRemovedTombstones([E|ElemsRest]=Elems, [{K,Ts}|DictRest]=Dict) -> + if + E == K -> + [{E,Ts}|elemsWithRemovedTombstones(ElemsRest, DictRest)]; + E > K -> + elemsWithRemovedTombstones(Elems, DictRest); + true -> + [{E,[]}|elemsWithRemovedTombstones(ElemsRest, Dict)] + end. + + +-spec update(effect(), set()) -> {ok, set()}. +update({add, Elems}, Dict) -> + {ok, addElems(Elems, Dict,[])}; +update({remove,Elems,Token}, Dict) -> + {ok, addElems(Elems, Dict, [Token])}. + +addElems([], Dict, _) -> Dict; +addElems(Elems, [], NewTombs) -> [{E, NewTombs} || {E,_} <- Elems]; +addElems([{E,RemovedTombstones}|ElemsRest]=Elems, [{K,Ts}|DictRest]=Dict, NewTombs) -> + if + E == K -> + [{E, NewTombs ++ (Ts -- RemovedTombstones)}|addElems(ElemsRest, DictRest, NewTombs)]; + E > K -> + [{K,Ts}|addElems(Elems, DictRest, NewTombs)]; + true -> + [{E, NewTombs}|addElems(ElemsRest, Dict, NewTombs)] + end. + + + -spec equal(set(), set()) -> boolean(). +equal(ORDictA, ORDictB) -> + ORDictA == ORDictB. % Everything inside is ordered, so this should work + + +-define(TAG, 77). +-define(V1_VERS, 1). + +-spec to_binary(set()) -> binary_set(). +to_binary(Set) -> + %% @TODO something smarter + <>. + +from_binary(<>) -> + %% @TODO something smarter + {ok, binary_to_term(Bin)}. + + + + + +is_operation({add, _Elem}) -> true; +is_operation({add_all, L}) when is_list(L) -> true; +is_operation({remove, _Elem}) -> + true; +is_operation({remove_all, L}) when is_list(L) -> true; +is_operation(_) -> false. + +require_state_downstream(_) -> true. \ No newline at end of file diff --git a/test/prop_crdt_set_rw.erl b/test/prop_crdt_set_rw.erl new file mode 100644 index 000000000..ee66fd0f6 --- /dev/null +++ b/test/prop_crdt_set_rw.erl @@ -0,0 +1,65 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_set_rw). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_orset_spec/0, set_op/0, rem_wins_set_spec/1]). + + +prop_orset_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_set_rw, fun set_op/0, fun rem_wins_set_spec/1). + + +rem_wins_set_spec(Operations1) -> + Operations = lists:flatmap(fun normalizeOperation/1, Operations1), + Removed = + [X || + % such that there is a remove operation for X + {RemClock, {remove, X}} <- Operations, + % and there is no add operation after the remove + [] == [Y || {AddClock, {add, Y}} <- Operations, X == Y, crdt_properties:clock_le(RemClock, AddClock)] + ], + Added = lists:usort([X || {_, {add, X}} <- Operations]), + Added -- Removed. + +% transforms add_all and remove_all into single operations +normalizeOperation({Clock, {add_all, Elems}}) -> + [{Clock, {add, Elem}} || Elem <- Elems]; +normalizeOperation({Clock, {remove_all, Elems}}) -> + [{Clock, {remove, Elem}} || Elem <- Elems]; +normalizeOperation(X) -> + [X]. + +% generates a random counter operation +set_op() -> + oneof([ + {add, set_element()}, + {add_all, list(set_element())}, + {remove, set_element()}, + {remove_all, list(set_element())} + ]). + +set_element() -> + oneof([a,b]). + From 78e6490cc2745012e35f2bb98aea216ce3190994 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Tue, 4 Oct 2016 19:49:56 +0200 Subject: [PATCH 155/426] first version of add-wins map --- src/antidote_crdt.erl | 5 +- src/antidote_crdt_gmap.erl | 8 +- src/antidote_crdt_integer.erl | 7 +- src/antidote_crdt_map_aw.erl | 180 ++++++++++++++++++++++++++++++++++ test/crdt_properties.erl | 2 + test/prop_crdt_integer.erl | 9 +- test/prop_crdt_map_aw.erl | 111 +++++++++++++++++++++ 7 files changed, 314 insertions(+), 8 deletions(-) create mode 100644 src/antidote_crdt_map_aw.erl create mode 100644 test/prop_crdt_map_aw.erl diff --git a/src/antidote_crdt.erl b/src/antidote_crdt.erl index 961e41a0e..3896f1bd4 100644 --- a/src/antidote_crdt.erl +++ b/src/antidote_crdt.erl @@ -31,9 +31,12 @@ antidote_crdt_rga, antidote_crdt_bcounter, antidote_crdt_mvreg, + antidote_crdt_lwwreg, antidote_crdt_map, antidote_crdt_gmap, - antidote_crdt_set_rw + antidote_crdt_set_rw, + antidote_crdt_integer, + antidote_crdt_map_aw ]). -export([is_type/1 diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index 069530ec4..37b4adafb 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -37,21 +37,21 @@ -endif. --type gmap() :: dict:dict(). +-type gmap() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). -type gmap_op() :: {update, nested_op()} | {update, [nested_op()]}. --type nested_op() :: {{Key::term(), Type::atom }, Op::term()}. +-type nested_op() :: {{Key::term(), Type::atom() }, Op::term()}. -type gmap_effect() :: {update, nested_downstream()} | {update, [nested_downstream()]}. --type nested_downstream() :: {{Key::term(), Type::atom }, Op::term()}. +-type nested_downstream() :: {{Key::term(), Type::atom() }, Op::term()}. -spec new() -> gmap(). new() -> dict:new(). --spec value(gmap()) -> [{{Key::term(), Type::atom}, Value::term()}]. +-spec value(gmap()) -> [{{Key::term(), Type::atom()}, Value::term()}]. value(Map) -> lists:sort([{{Key,Type}, Type:value(Value)} || {{Key, Type}, Value} <- dict:to_list(Map)]). diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl index 6d862d025..f9d940e4b 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/antidote_crdt_integer.erl @@ -65,7 +65,10 @@ downstream({increment, N}, _State) -> {ok, {increment, N}}; downstream({set, N}, {Vals, Delta}) -> Overridden = [Tag || {Tag, _} <- Vals], - {ok, {set, unique(), Overridden, N-Delta}}. + {ok, {set, unique(), Overridden, N-Delta}}; +downstream(reset, State) -> + % resetting means setting value to 0 + downstream({set, 0}, State). unique() -> crypto:strong_rand_bytes(20). @@ -104,11 +107,13 @@ from_binary(Bin) -> -spec is_operation(term()) -> boolean(). is_operation({increment, N}) when is_integer(N) -> true; is_operation({set, N}) when is_integer(N) -> true; +is_operation(reset) -> true; is_operation(_) -> false. %% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt %% to generate downstream effect require_state_downstream({set,_}) -> true; +require_state_downstream(reset) -> true; require_state_downstream(_) -> false. diff --git a/src/antidote_crdt_map_aw.erl b/src/antidote_crdt_map_aw.erl new file mode 100644 index 000000000..3d1ffd8c4 --- /dev/null +++ b/src/antidote_crdt_map_aw.erl @@ -0,0 +1,180 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +%% @doc module antidote_crdt_map - A add-wins map +%% +%% This map forwards all operations to the embedded CRDTs. +%% Deleting a key tries to reset the entry to its initial state +%% +%% An element exists in a map, if there is at least one update on the key, which is not followed by a remove + +-module(antidote_crdt_map_aw). + +-behaviour(antidote_crdt). + +%% API +-export([new/0, value/1, update/2, equal/2, + to_binary/1, from_binary/1, is_operation/1, downstream/2, require_state_downstream/1]). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + + +-type typedKey() :: {Key::term(), Type::atom()}. +-type token() :: term(). +-type state() :: dict:dict(typedKey(), {[token()], NestedState::term()}). +-type op() :: + {update, nested_op()} + | {update, [nested_op()]} + | {remove, typedKey()} + | {remove, [typedKey()]}. +-type nested_op() :: {typedKey(), Op::term()}. +-type effect() :: + {update, [nested_downstream()], AddedToken::token()} + | {remove, [nested_downstream()]}. +-type nested_downstream() :: {typedKey(), none | {ok, Effect::term()}, RemovedTokens::[token()]}. + +-spec new() -> state(). +new() -> + dict:new(). + +-spec value(state()) -> [{typedKey(), Value::term()}]. +value(Map) -> + lists:sort([{{Key,Type}, Type:value(Value)} || {{Key, Type}, {Tokens, Value}} <- dict:to_list(Map), Tokens =/= []]). + +-spec require_state_downstream(op()) -> boolean(). +require_state_downstream(_Op) -> + true. + + +-spec downstream(op(), state()) -> {ok, effect()}. +downstream({update, {{Key, Type}, Op}}, CurrentMap) -> + downstream({update, [{{Key, Type}, Op}]}, CurrentMap); +downstream({update, NestedOps}, CurrentMap) -> + Token = unique(), + {ok, {update, [generateDownstreamUpdate(Op, CurrentMap) || Op <- NestedOps], Token}}; +downstream({remove, {Key, Type}}, CurrentMap) -> + downstream({remove, [{Key, Type}]}, CurrentMap); +downstream({remove, Keys}, CurrentMap) -> + {ok, {remove, [generateDownstreamRemove(Key, CurrentMap) || Key <- Keys]}}. + + +-spec generateDownstreamUpdate({typedKey(), Op::term()}, state()) -> nested_downstream(). +generateDownstreamUpdate({{Key,Type}, Op}, CurrentMap) -> + {CurrentTokens, CurrentState} = + case dict:is_key({Key, Type}, CurrentMap) of + true -> dict:fetch({Key, Type}, CurrentMap); + false -> {[], Type:new()} + end, + {ok, DownstreamEffect} = Type:downstream(Op, CurrentState), + {{Key, Type}, {ok, DownstreamEffect}, CurrentTokens}. + + +-spec generateDownstreamRemove(typedKey(), state()) -> nested_downstream(). +generateDownstreamRemove({Key,Type}, CurrentMap) -> + {CurrentTokens, CurrentState} = + case dict:is_key({Key, Type}, CurrentMap) of + true -> dict:fetch({Key, Type}, CurrentMap); + false -> {[], Type:new()} + end, + DownstreamEffect = + case Type:is_operation(reset) of + true -> + {ok, _} = Type:downstream(reset, CurrentState); + false -> + none + end, + {{Key, Type}, DownstreamEffect, CurrentTokens}. + + +unique() -> + crypto:strong_rand_bytes(20). + +-spec update(effect(), state()) -> {ok, state()}. +update({update, NestedEffects, AddedToken}, State) -> + {ok, lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, NestedEffects)}; +update({remove, NestedEffects}, State) -> + {ok, lists:foldl(fun(E, S) -> update(E, [], S) end, State, NestedEffects)}. + +update({{Key,Type}, {ok, Op}, RemovedTokens}, NewTokens, Map) -> + case dict:find({Key,Type}, Map) of + {ok, {Tokens, State}} -> + UpdatedTokens = NewTokens ++ (Tokens -- RemovedTokens), + {ok, UpdatedState} = Type:update(Op, State), + dict:store({Key, Type}, {UpdatedTokens, UpdatedState}, Map); + error -> + NewValue = Type:new(), + {ok, NewValueUpdated} = Type:update(Op, NewValue), + dict:store({Key, Type}, {NewTokens, NewValueUpdated}, Map) + end; +update({{Key,Type}, none, RemovedTokens}, NewTokens, Map) -> + case dict:find({Key,Type}, Map) of + {ok, {Tokens, State}} -> + UpdatedTokens = NewTokens ++ (Tokens -- RemovedTokens), + dict:store({Key, Type}, {UpdatedTokens, State}, Map); + error -> + NewValue = Type:new(), + dict:store({Key, Type}, {NewTokens, NewValue}, Map) + end. + + + +equal(Map1, Map2) -> + Map1 == Map2. % TODO better implementation (recursive equals) + + +-define(TAG, 101). +-define(V1_VERS, 1). + +to_binary(Policy) -> + %% @TODO okthing smarter + <>. + +from_binary(<>) -> + %% @TODO okthing smarter + {ok, binary_to_term(Bin)}. + +is_operation(Operation) -> + case Operation of + {update, {{_Key, Type}, Op}} -> + antidote_crdt:is_type(Type) + andalso Type:is_operation(Op); + {update, Ops} when is_list(Ops) -> + distinct([Key || {Key, _} <- Ops]) + andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); + {remove, {_Key, Type}} -> + antidote_crdt:is_type(Type); + {remove, Keys} when is_list(Keys) -> + distinct(Keys) + andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Keys); + _ -> + false + end. + +distinct([]) -> true; +distinct([X|Xs]) -> + not lists:member(X, Xs) andalso distinct(Xs). + + + + + + diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl index 04f9bd98f..88b70e2c3 100644 --- a/test/crdt_properties.erl +++ b/test/crdt_properties.erl @@ -77,6 +77,8 @@ clock_le(A, B) -> % executes/checks the specification checkSpec(Crdt, Ops, Spec) -> + % check that the CRDT is registered: + true = antidote_crdt:is_type(Crdt), % check that all generated operatiosn are valid: _ = [case Crdt:is_operation(Op) of true -> true; diff --git a/test/prop_crdt_integer.erl b/test/prop_crdt_integer.erl index 186a7f6bb..d93006c80 100644 --- a/test/prop_crdt_integer.erl +++ b/test/prop_crdt_integer.erl @@ -31,7 +31,8 @@ prop_counter_spec() -> crdt_properties:crdt_satisfies_spec(antidote_crdt_integer, fun op/0, fun spec/1). -spec(Operations) -> +spec(Operations1) -> + Operations = [normalizeOp(Op) || Op <- Operations1], ConcurrentValues = [{Clock, Val} || {Clock, {set, Val}} <- Operations, [] == [Clock2 || {Clock2, {set, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)]], @@ -47,10 +48,14 @@ spec(Operations) -> WithDelta = [Val + Delta(Clock) || {Clock,Val} <- ConcurrentValues2], lists:max(WithDelta). +normalizeOp({Clock, reset}) -> {Clock, {set, 0}}; +normalizeOp(Op) -> Op. + % generates a random counter operation op() -> oneof([ {set, integer()}, - {increment, integer()} + {increment, integer()}, + reset ]). diff --git a/test/prop_crdt_map_aw.erl b/test/prop_crdt_map_aw.erl new file mode 100644 index 000000000..252b70523 --- /dev/null +++ b/test/prop_crdt_map_aw.erl @@ -0,0 +1,111 @@ +%% ------------------------------------------------------------------- +%% +%% Copyright (c) 2014 SyncFree Consortium. All Rights Reserved. +%% +%% This file is provided to you under the Apache License, +%% Version 2.0 (the "License"); you may not use this file +%% except in compliance with the License. You may obtain +%% a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% +%% ------------------------------------------------------------------- + +-module(prop_crdt_map_aw). + +-define(PROPER_NO_TRANS, true). +-include_lib("proper/include/proper.hrl"). + +%% API +-export([prop_map_spec/0]). + + +prop_map_spec() -> + crdt_properties:crdt_satisfies_spec(antidote_crdt_map_aw, fun op/0, fun spec/1). + + +spec(Operations1) -> + Operations = lists:flatmap(fun normalizeOp/1, Operations1), + % the keys in the map are the ones that were updated and not deleted yet + Keys = lists:usort([Key || + % has an update + {AddClock, {update, {Key, _}}} <- Operations, + % no remove after the update: + [] == [Y || {RemoveClock, {remove, Y}} <- Operations, Key == Y, crdt_properties:clock_le(AddClock, RemoveClock)] + ]), + GroupedByKey = [{Key, nestedOps(Operations, Key)} || Key <- Keys], + NestedSpec = [{{Key,Type}, nestedSpec(Type, Ops)} || {{Key,Type}, Ops} <- GroupedByKey], + %% TODO add reset operations + lists:sort(NestedSpec). + +nestedOps(Operations, {_,Type}=Key) -> + Resets = + case Type:is_operation(reset) of + true -> + [{Clock, reset} || {Clock, {remove, Key2}} <- Operations, Key == Key2]; + false -> [] + end, + Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. + +nestedSpec(antidote_crdt_map_aw, Ops) -> spec(Ops); +nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); +nestedSpec(antidote_crdt_integer, Ops) -> prop_crdt_integer:spec(Ops). + +% normalizes operations (update-lists into single update-operations) +normalizeOp({Clock, {update, List}}) when is_list(List) -> + [{Clock, {update, X}} || X <- List]; +normalizeOp({Clock, {remove, List}}) when is_list(List) -> + [{Clock, {remove, X}} || X <- List]; +normalizeOp(X) -> [X]. + + +% generates a random operation +op() -> ?SIZED(Size, op(Size)). +op(Size) -> + oneof([ + {update, nestedOp(Size)}, + {update, ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, []))}, + {remove, typed_key()}, + {remove, ?LET(L, list(typed_key()), lists:usort(L))} + ]). + +removeDuplicateKeys([], _) -> []; +removeDuplicateKeys([{Key,Op}|Rest], Keys) -> + case lists:member(Key, Keys) of + true -> removeDuplicateKeys(Rest, Keys); + false -> [{Key, Op}|removeDuplicateKeys(Rest, [Key|Keys])] + end. + +nestedOp(Size) -> + oneof( + [ + {{key(), antidote_crdt_integer}, prop_crdt_integer:op()}, + {{key(), antidote_crdt_orset}, prop_crdt_orset:set_op()} + ] + ++ + if + Size > 1 -> + [{{key(), antidote_crdt_map_aw}, ?LAZY(op(Size div 2))}]; + true -> [] + end + ). + +typed_key() -> {key(), crdt_type()}. + +crdt_type() -> + oneof([antidote_crdt_integer, antidote_crdt_orset, antidote_crdt_map_aw]). + +key() -> + oneof([a,b,c,d]). + + + + + From ad0d1fa1905b265c0ae326093ddc665ded41cd1c Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Wed, 5 Oct 2016 17:31:25 +0200 Subject: [PATCH 156/426] added reset function to more CRDTs --- src/antidote_crdt_gmap.erl | 28 ++++++- src/antidote_crdt_integer.erl | 3 +- src/antidote_crdt_map_aw.erl | 45 +++++++++- src/antidote_crdt_mvreg.erl | 15 +++- src/antidote_crdt_orset.erl | 17 +++- src/antidote_crdt_set_rw.erl | 154 ++++++++++++++++++++++++++-------- test/crdt_properties.erl | 19 ++++- test/prop_crdt_gmap.erl | 23 +++-- test/prop_crdt_map_aw.erl | 16 ++-- test/prop_crdt_mvreg.erl | 11 ++- test/prop_crdt_orset.erl | 7 +- test/prop_crdt_set_rw.erl | 22 +++-- 12 files changed, 288 insertions(+), 72 deletions(-) diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index 37b4adafb..aaadc7049 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -40,7 +40,8 @@ -type gmap() :: dict:dict({Key::term(), Type::atom()}, NestedState::term()). -type gmap_op() :: {update, nested_op()} - | {update, [nested_op()]}. + | {update, [nested_op()]} + | reset. -type nested_op() :: {{Key::term(), Type::atom() }, Op::term()}. -type gmap_effect() :: {update, nested_downstream()} @@ -70,7 +71,20 @@ downstream({update, {{Key, Type}, Op}}, CurrentMap) -> {ok, DownstreamOp} = Type:downstream(Op, CurrentValue), {ok, {update, {{Key, Type}, DownstreamOp}}}; downstream({update, Ops}, CurrentMap) when is_list(Ops) -> - {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}. + {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}; +downstream(reset, CurrentMap) -> + % calls reset on all embedded keys which support reset + Reset = + fun({{Key, Type}, State}) -> + case Type:is_operation(reset) of + true -> + {ok, EmbeddedEffect} = Type:downstream(reset, State), + [{update, {{Key, Type}, EmbeddedEffect}}]; + false -> [] + end + end, + DownstreamResets = lists:flatmap(Reset, dict:to_list(CurrentMap)), + {ok, {update, DownstreamResets}}. -spec update(gmap_effect(), gmap()) -> {ok, gmap()}. update({update, {{Key, Type}, Op}}, Map) -> @@ -114,6 +128,7 @@ is_operation(Operation) -> {update, Ops} when is_list(Ops) -> distinct([Key || {Key, _} <- Ops]) andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); + reset -> true; _ -> false end. @@ -137,6 +152,15 @@ update_test() -> ?assertMatch({update, {{key1, antidote_crdt_lwwreg}, {_TS, <<"test">>}}}, DownstreamOp), {ok, Map2} = update(DownstreamOp, Map1), ?assertEqual([{{key1, antidote_crdt_lwwreg}, <<"test">>}], value(Map2)). + +update2_test() -> + Map1 = new(), + {ok, Effect1} = downstream({update,[{{a,antidote_crdt_orset},{add,a}}]}, Map1), + {ok, Map2} = update(Effect1, Map1), + {ok, Effect2} = downstream(reset, Map2), + {ok, Map3} = update(Effect2, Map2), + ?assertEqual([{{a, antidote_crdt_orset}, []}], value(Map3)). + -endif. diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl index f9d940e4b..42a701580 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/antidote_crdt_integer.erl @@ -45,7 +45,8 @@ -type state() :: {[{term(), integer()}], integer()}. -type update() :: {increment, integer()} - | {set, integer()}. + | {set, integer()} + | reset. -type effect() :: {increment, integer()} | {set, term(), [term()], integer()}. diff --git a/src/antidote_crdt_map_aw.erl b/src/antidote_crdt_map_aw.erl index 3d1ffd8c4..2f92dbb29 100644 --- a/src/antidote_crdt_map_aw.erl +++ b/src/antidote_crdt_map_aw.erl @@ -45,7 +45,8 @@ {update, nested_op()} | {update, [nested_op()]} | {remove, typedKey()} - | {remove, [typedKey()]}. + | {remove, [typedKey()]} + | reset. -type nested_op() :: {typedKey(), Op::term()}. -type effect() :: {update, [nested_downstream()], AddedToken::token()} @@ -74,7 +75,11 @@ downstream({update, NestedOps}, CurrentMap) -> downstream({remove, {Key, Type}}, CurrentMap) -> downstream({remove, [{Key, Type}]}, CurrentMap); downstream({remove, Keys}, CurrentMap) -> - {ok, {remove, [generateDownstreamRemove(Key, CurrentMap) || Key <- Keys]}}. + {ok, {remove, [generateDownstreamRemove(Key, CurrentMap) || Key <- Keys]}}; +downstream(reset, CurrentMap) -> + % reset removes all keys + AllKeys = [Key || {Key, _Val} <- value(CurrentMap)], + downstream({remove, AllKeys}, CurrentMap). -spec generateDownstreamUpdate({typedKey(), Op::term()}, state()) -> nested_downstream(). @@ -165,6 +170,7 @@ is_operation(Operation) -> {remove, Keys} when is_list(Keys) -> distinct(Keys) andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Keys); + reset -> true; _ -> false end. @@ -176,5 +182,40 @@ distinct([X|Xs]) -> +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). + +reset1_test() -> + Set0 = new(), + % DC1: a.incr + {ok, Incr1} = downstream({update, {{a, antidote_crdt_integer}, {increment, 1}}}, Set0), + {ok, Set1a} = update(Incr1, Set0), + % DC1 reset + {ok, Reset1} = downstream(reset, Set1a), + {ok, Set1b} = update(Reset1, Set1a), + % DC2 a.remove + {ok, Remove1} = downstream({remove, {a, antidote_crdt_integer}}, Set0), + {ok, Set2a} = update(Remove1, Set0), + % DC2 --> DC1 + {ok, Set1c} = update(Remove1, Set1b), + % DC1 reset + {ok, Reset2} = downstream(reset, Set1c), + {ok, Set1d} = update(Reset2, Set1c), + % DC1: a.incr + {ok, Incr2} = downstream({update, {{a, antidote_crdt_integer}, {increment, 0}}}, Set1d), + {ok, Set1e} = update(Incr2, Set1d), + + ?assertEqual([], value(Set2a)), + ?assertEqual([], value(Set1d)), + ?assertEqual([{{a, antidote_crdt_integer}, 1}], value(Set1e)). + + + + + +-endif. + diff --git a/src/antidote_crdt_mvreg.erl b/src/antidote_crdt_mvreg.erl index 171b499e0..9391d9931 100644 --- a/src/antidote_crdt_mvreg.erl +++ b/src/antidote_crdt_mvreg.erl @@ -57,7 +57,9 @@ %% TODO: make opaque -type mvreg() :: [{term(), uniqueToken()}]. -type uniqueToken() :: term(). --type mvreg_effect() :: {Value::term(), uniqueToken(), Overridden::[uniqueToken()]}. +-type mvreg_effect() :: + {Value::term(), uniqueToken(), Overridden::[uniqueToken()]} + | {reset, Overridden::[uniqueToken()]}. -type mvreg_op() :: {assign, term()}. @@ -81,7 +83,10 @@ value(MVReg) -> downstream({assign, Value}, MVReg) -> Token = unique(), Overridden = [Tok || {_, Tok} <- MVReg], - {ok, {Value, Token, Overridden}}. + {ok, {Value, Token, Overridden}}; +downstream(reset, MVReg) -> + Overridden = [Tok || {_, Tok} <- MVReg], + {ok, {reset, Overridden}}. -spec unique() -> uniqueToken(). unique() -> @@ -93,7 +98,10 @@ update({Value, Token, Overridden}, MVreg) -> % remove overridden values MVreg2 = [{V,T} || {V,T} <- MVreg, not lists:member(T, Overridden)], % insert new value - {ok, insertSorted({Value, Token}, MVreg2)}. + {ok, insertSorted({Value, Token}, MVreg2)}; +update({reset, Overridden}, MVreg) -> + MVreg2 = [{V,T} || {V,T} <- MVreg, not lists:member(T, Overridden)], + {ok, MVreg2}. % insert value into sorted list insertSorted(A, []) -> [A]; @@ -122,6 +130,7 @@ from_binary(<>) -> %% that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). is_operation({assign, _}) -> true; +is_operation(reset) -> true; is_operation(_) -> false. require_state_downstream(_) -> diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index 684c025b7..d5f72e1c9 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -75,8 +75,12 @@ -type binary_orset() :: binary(). %% A binary that from_binary/1 will operate on. --type orset_op() :: {add, member()} | {remove, member()} | - {add_all, [member()]} | {remove_all, [member()]}. +-type orset_op() :: + {add, member()} + | {remove, member()} + | {add_all, [member()]} + | {remove_all, [member()]} + | reset. -type member() :: term(). @@ -132,7 +136,10 @@ downstream({remove_all,Elems}, ORDict) -> ToRemove = lists:foldl(fun(Elem, Sum) -> Sum++[{Elem, value({tokens, Elem}, ORDict)}] end, [], Elems), - {ok, {remove_all, ToRemove}}. + {ok, {remove_all, ToRemove}}; +downstream(reset, ORDict) -> + % reset is like removing all elements + downstream({remove_all, value(ORDict)}, ORDict). %% @doc apply downstream operations and update an `orset()'. %% The first parameter denotes this operation is for adding or removing elements. @@ -249,6 +256,7 @@ is_operation({add_all, L}) when is_list(L) -> true; is_operation({remove, _Elem}) -> true; is_operation({remove_all, L}) when is_list(L) -> true; +is_operation(reset) -> true; is_operation(_) -> false. require_state_downstream({add,_}) -> @@ -256,7 +264,8 @@ require_state_downstream({add,_}) -> require_state_downstream({add_all,_}) -> false; require_state_downstream({remove,_}) -> true; -require_state_downstream({remove_all, _}) -> true. +require_state_downstream({remove_all, _}) -> true; +require_state_downstream(reset) -> true. %% =================================================================== %% EUnit tests diff --git a/src/antidote_crdt_set_rw.erl b/src/antidote_crdt_set_rw.erl index d4a52bab1..e373b63e8 100644 --- a/src/antidote_crdt_set_rw.erl +++ b/src/antidote_crdt_set_rw.erl @@ -47,74 +47,87 @@ -endif. -export_type([set/0, binary_set/0, set_op/0]). --opaque set() :: orddict:orddict(term(), [token()]). +-opaque set() :: {ResetTokens::[token()], orddict:orddict(term(), [token()])}. -type binary_set() :: binary(). %% A binary that from_binary/1 will operate on. --type set_op() :: {add, member()} | {remove, member()} | - {add_all, [member()]} | {remove_all, [member()]}. +-type set_op() :: + {add, member()} + | {remove, member()} + | {add_all, [member()]} + | {remove_all, [member()]} + | reset. -type token() :: term(). -type effect() :: - {add, [{member(), [token()]}]} - | {remove, [{member(), [token()]}], token()}. + {add, [{member(), RemTokens::[token()]}], ResetTokens::[token()]} + | {remove, [{member(), RemTokens::[token()]}], NewRemToken::token(), ResetTokens::[token()]} + | {reset, [{member(), RemTokens::[token()]}], OldResetTokens::[token()], NewResetToken::token()}. -type member() :: term(). -spec new() -> set(). new() -> - orddict:new(). + {[], orddict:new()}. -spec value(set()) -> [member()]. -value(Dict) -> +value({_,Dict}) -> [Val || {Val, []} <- orddict:to_list(Dict)]. -spec downstream(set_op(), set()) -> {ok, effect()}. -downstream({add, Elem}, Dict) -> - downstream({add_all, [Elem]}, Dict); -downstream({add_all,Elems}, Dict) -> - {ok, {add, elemsWithRemovedTombstones(lists:usort(Elems), Dict)}}; -downstream({remove, Elem}, Dict) -> - downstream({remove_all, [Elem]}, Dict); -downstream({remove_all, Elems}, Dict) -> -%% {ok, {remove, [{E,[]} || E <- lists:usort(Elems)], unique()}}. -% TODO optimization: - {ok, {remove, elemsWithRemovedTombstones(lists:usort(Elems), Dict), unique()}}. +downstream({add, Elem}, State) -> + downstream({add_all, [Elem]}, State); +downstream({add_all,Elems}, {ResetTokens, Dict}) -> + {ok, {add, elemsWithRemovedTombstones(lists:usort(Elems), Dict, ResetTokens), ResetTokens}}; +downstream({remove, Elem}, State) -> + downstream({remove_all, [Elem]}, State); +downstream({remove_all, Elems}, {ResetTokens, Dict}) -> + {ok, {remove, elemsWithRemovedTombstones(lists:usort(Elems), Dict, ResetTokens), unique(), ResetTokens}}; +downstream(reset, {ResetTokens, Dict}) -> + RemovedTombstones = elemsWithRemovedTombstones(lists:usort(orddict:fetch_keys(Dict)), Dict, ResetTokens), + {ok, {reset, RemovedTombstones, ResetTokens, unique()}}. %% @doc generate a unique identifier (best-effort). unique() -> crypto:strong_rand_bytes(20). -elemsWithRemovedTombstones([], _Dict) -> []; -elemsWithRemovedTombstones(Elems, []) -> [{E,[]} || E <- Elems]; -elemsWithRemovedTombstones([E|ElemsRest]=Elems, [{K,Ts}|DictRest]=Dict) -> +elemsWithRemovedTombstones([], _Dict, _ResetTokens) -> []; +elemsWithRemovedTombstones(Elems, [], ResetTokens) -> [{E,ResetTokens} || E <- Elems]; +elemsWithRemovedTombstones([E|ElemsRest]=Elems, [{K,Ts}|DictRest]=Dict, ResetTokens) -> if E == K -> - [{E,Ts}|elemsWithRemovedTombstones(ElemsRest, DictRest)]; + [{E,Ts++ResetTokens}|elemsWithRemovedTombstones(ElemsRest, DictRest, ResetTokens)]; E > K -> - elemsWithRemovedTombstones(Elems, DictRest); + elemsWithRemovedTombstones(Elems, DictRest, ResetTokens); true -> - [{E,[]}|elemsWithRemovedTombstones(ElemsRest, Dict)] + [{E,ResetTokens}|elemsWithRemovedTombstones(ElemsRest, Dict, ResetTokens)] end. -spec update(effect(), set()) -> {ok, set()}. -update({add, Elems}, Dict) -> - {ok, addElems(Elems, Dict,[])}; -update({remove,Elems,Token}, Dict) -> - {ok, addElems(Elems, Dict, [Token])}. - -addElems([], Dict, _) -> Dict; -addElems(Elems, [], NewTombs) -> [{E, NewTombs} || {E,_} <- Elems]; -addElems([{E,RemovedTombstones}|ElemsRest]=Elems, [{K,Ts}|DictRest]=Dict, NewTombs) -> +update({add, Elems, ObservedResetTokens}, {ResetTokens, Dict}) -> + NewResetTokens = ResetTokens -- ObservedResetTokens, + {ok, {ResetTokens, addElems(Elems, Dict, [], NewResetTokens)}}; +update({remove,Elems,Token, ObservedResetTokens}, {ResetTokens, Dict}) -> + NewResetTokens = ResetTokens -- ObservedResetTokens, + {ok, {ResetTokens, addElems(Elems, Dict, [Token], NewResetTokens)}}; +update({reset, Elems, OldResetTokens, NewResetToken}, {ResetTokens, Dict}) -> + Dict2 = addElems(Elems, Dict, [], []), + Dict3 = [{X, [NewResetToken|Tokens--OldResetTokens]} || {X,Tokens} <- Dict2], + {ok, {[NewResetToken] ++ (ResetTokens -- OldResetTokens), Dict3}}. + + +addElems([], Dict, _, _) -> Dict; +addElems(Elems, [], NewTombs, NewEntryTombs) -> [{E, NewTombs++NewEntryTombs} || {E,_} <- Elems]; +addElems([{E,RemovedTombstones}|ElemsRest]=Elems, [{K,Ts}|DictRest]=Dict, NewTombs, NewEntryTombs) -> if E == K -> - [{E, NewTombs ++ (Ts -- RemovedTombstones)}|addElems(ElemsRest, DictRest, NewTombs)]; + [{E, NewTombs ++ (Ts -- RemovedTombstones)}|addElems(ElemsRest, DictRest, NewTombs, NewEntryTombs)]; E > K -> - [{K,Ts}|addElems(Elems, DictRest, NewTombs)]; + [{K,Ts}|addElems(Elems, DictRest, NewTombs, NewEntryTombs)]; true -> - [{E, NewTombs}|addElems(ElemsRest, Dict, NewTombs)] + [{E, NewTombs++NewEntryTombs}|addElems(ElemsRest, Dict, NewTombs, NewEntryTombs)] end. @@ -144,6 +157,77 @@ is_operation({add_all, L}) when is_list(L) -> true; is_operation({remove, _Elem}) -> true; is_operation({remove_all, L}) when is_list(L) -> true; +is_operation(reset) -> true; is_operation(_) -> false. -require_state_downstream(_) -> true. \ No newline at end of file +require_state_downstream(_) -> true. + + + +%% =================================================================== +%% EUnit tests +%% =================================================================== +-ifdef(TEST). + +reset1_test() -> + Set0 = new(), + % DC1 reset + {ok, ResetEffect} = downstream(reset, Set0), + {ok, Set1a} = update(ResetEffect, Set0), + % DC1 add + {ok, Add1Effect} = downstream({add, a}, Set1a), + {ok, Set1b} = update(Add1Effect, Set1a), + % DC2 add + {ok, Add2Effect} = downstream({add, a}, Set0), + {ok, Set2a} = update(Add2Effect, Set0), + % pull 2 from DC1 to DC2 + {ok, Set2b} = update(ResetEffect, Set2a), + {ok, Set2c} = update(Add1Effect, Set2b), + + io:format("ResetEffect = ~p~n", [ResetEffect]), + io:format("Add1Effect = ~p~n", [Add1Effect]), + io:format("Add2Effect = ~p~n", [Add2Effect]), + + io:format("Set1a = ~p~n", [Set1a]), + io:format("Set1b = ~p~n", [Set1b]), + io:format("Set2a = ~p~n", [Set2a]), + io:format("Set2b = ~p~n", [Set2b]), + io:format("Set2c = ~p~n", [Set2c]), + + ?assertEqual([], value(Set1a)), + ?assertEqual([a], value(Set1b)), + ?assertEqual([a], value(Set2a)), + ?assertEqual([], value(Set2b)), + ?assertEqual([a], value(Set2c)). + + +reset2_test() -> + Set0 = new(), + % DC1 reset + {ok, Reset1Effect} = downstream(reset, Set0), + {ok, Set1a} = update(Reset1Effect, Set0), + % DC1 --> Dc2 + {ok, Set2a} = update(Reset1Effect, Set0), + % DC2 reset + {ok, Reset2Effect} = downstream(reset, Set2a), + {ok, Set2b} = update(Reset2Effect, Set2a), + % DC2 add + {ok, Add2Effect} = downstream({add, a}, Set2b), + {ok, Set2c} = update(Add2Effect, Set2b), + % DC3 add + {ok, Add3Effect} = downstream({add, a}, Set0), + {ok, Set3a} = update(Add3Effect, Set0), + % DC1 --> DC3 + {ok, Set3b} = update(Reset1Effect, Set3a), + % DC2 --> DC3 + {ok, Set3c} = update(Reset2Effect, Set3b), + % DC2 --> DC3 + {ok, Set3d} = update(Add2Effect, Set3c), + + + ?assertEqual([], value(Set1a)), + ?assertEqual([a], value(Set2c)), + ?assertEqual([a], value(Set3d)). + + +-endif. diff --git a/test/crdt_properties.erl b/test/crdt_properties.erl index 88b70e2c3..6388f7c01 100644 --- a/test/crdt_properties.erl +++ b/test/crdt_properties.erl @@ -25,7 +25,7 @@ --export([crdt_satisfies_spec/3, clock_le/2]). +-export([crdt_satisfies_spec/3, clock_le/2, subcontext/2]). -export_type([clocked_operation/0]). @@ -75,6 +75,9 @@ clock_le(A, B) -> lists:all(fun(R) -> maps:get(R, A) =< maps:get(R, B, 0) end, maps:keys(A)). +subcontext(Clock, Operations) -> + [{OpClock, Op} || {OpClock, Op} <- Operations, clock_le(OpClock, Clock), not clock_le(Clock, OpClock)]. + % executes/checks the specification checkSpec(Crdt, Ops, Spec) -> % check that the CRDT is registered: @@ -108,6 +111,7 @@ checkSpecEnd(Crdt, Spec, EndState, R) -> SpecValue = Spec(VisibleOperations), ?WHENFAIL( begin +%% printState(EndState), io:format("Reading value on ~p~n", [R]), io:format("Expected value: ~p~n", [SpecValue]), io:format("Actual value : ~p~n", [RValue]) @@ -194,4 +198,15 @@ checkBinaryEncoding(Crdt, EndState, R) -> end, Crdt:value(CrdtState) == Crdt:value(CrdtState2) )} - ]). \ No newline at end of file + ]). + + +%%printState(State) -> +%% [printReplicaState(R, ReplicaState) || {R, ReplicaState} <- maps:to_list(State)]. +%% +%%printReplicaState(R, S) -> +%% io:format("Replica ~p : ~n", [R]), +%% io:format(" State ~p : ~n", [S#test_replica_state.state]), +%% io:format(" operations ~p : ~n", [S#test_replica_state.operations]), +%% io:format(" downstreamOps ~p : ~n", [S#test_replica_state.downstreamOps]), +%% ok. \ No newline at end of file diff --git a/test/prop_crdt_gmap.erl b/test/prop_crdt_gmap.erl index 1c9a61a01..28334dbc0 100644 --- a/test/prop_crdt_gmap.erl +++ b/test/prop_crdt_gmap.erl @@ -34,10 +34,19 @@ prop_gmap_spec() -> spec(Operations1) -> Operations = lists:flatmap(fun normalizeOp/1, Operations1), Keys = lists:usort([Key || {_, {update, {Key, _}}} <- Operations]), - GroupedByKey = [{Key, [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2 ]} || Key <- Keys], + GroupedByKey = [{Key, nestedOps(Operations, Key)} || Key <- Keys], NestedSpec = [{{Key,Type}, nestedSpec(Type, Ops)} || {{Key,Type}, Ops} <- GroupedByKey], lists:sort(NestedSpec). +nestedOps(Operations, {_,Type}=Key) -> + Resets = + case Type:is_operation(reset) of + true -> + [{Clock, reset} || {Clock, reset} <- Operations]; + false -> [] + end, + Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. + nestedSpec(antidote_crdt_gmap, Ops) -> spec(Ops); nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); nestedSpec(antidote_crdt_counter, Ops) -> prop_crdt_counter:counter_spec(Ops). @@ -51,10 +60,14 @@ normalizeOp(X) -> [X]. % generates a random operation op() -> ?SIZED(Size, op(Size)). op(Size) -> - {update, oneof([ - nestedOp(Size), - ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, [])) - ])}. + frequency([ + % nested updates + {10, {update, oneof([ + nestedOp(Size), + ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, [])) + ])}}, + {1, reset} + ]). removeDuplicateKeys([], _) -> []; removeDuplicateKeys([{Key,Op}|Rest], Keys) -> diff --git a/test/prop_crdt_map_aw.erl b/test/prop_crdt_map_aw.erl index 252b70523..9130adef0 100644 --- a/test/prop_crdt_map_aw.erl +++ b/test/prop_crdt_map_aw.erl @@ -32,7 +32,7 @@ prop_map_spec() -> spec(Operations1) -> - Operations = lists:flatmap(fun normalizeOp/1, Operations1), + Operations = lists:flatmap(fun(Op) -> normalizeOp(Op, Operations1) end, Operations1), % the keys in the map are the ones that were updated and not deleted yet Keys = lists:usort([Key || % has an update @@ -59,11 +59,16 @@ nestedSpec(antidote_crdt_orset, Ops) -> prop_crdt_orset:add_wins_set_spec(Ops); nestedSpec(antidote_crdt_integer, Ops) -> prop_crdt_integer:spec(Ops). % normalizes operations (update-lists into single update-operations) -normalizeOp({Clock, {update, List}}) when is_list(List) -> +normalizeOp({Clock, {update, List}}, _) when is_list(List) -> [{Clock, {update, X}} || X <- List]; -normalizeOp({Clock, {remove, List}}) when is_list(List) -> +normalizeOp({Clock, {remove, List}}, _) when is_list(List) -> [{Clock, {remove, X}} || X <- List]; -normalizeOp(X) -> [X]. +normalizeOp({Clock, reset}, Operations) -> + % reset is like removing all current keys + Map = spec(crdt_properties:subcontext(Clock, Operations)), + Keys = [Key || {Key, _Val} <- Map], + [{Clock, {remove, X}} || X <- Keys]; +normalizeOp(X, _) -> [X]. % generates a random operation @@ -73,7 +78,8 @@ op(Size) -> {update, nestedOp(Size)}, {update, ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, []))}, {remove, typed_key()}, - {remove, ?LET(L, list(typed_key()), lists:usort(L))} + {remove, ?LET(L, list(typed_key()), lists:usort(L))}, + reset ]). removeDuplicateKeys([], _) -> []; diff --git a/test/prop_crdt_mvreg.erl b/test/prop_crdt_mvreg.erl index ba1f524e2..d63a43098 100644 --- a/test/prop_crdt_mvreg.erl +++ b/test/prop_crdt_mvreg.erl @@ -34,12 +34,19 @@ prop_mvreg_spec() -> spec(Operations) -> Values = [Val || {Clock, {assign, Val}} <- Operations, - [] == [Clock2 || {Clock2, {assign, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)]], + % all values, such that not overridden by other assign + [] == [Clock2 || {Clock2, {assign, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)], + % and not overridden by reset + [] == [Clock3 || {Clock3, reset} <- Operations, crdt_properties:clock_le(Clock, Clock3)] + ], lists:sort(Values). % generates a random counter operation op() -> - {assign, oneof([a,b,c,d,e,f,g,h,i])}. + frequency([ + {5, {assign, oneof([a,b,c,d,e,f,g,h,i])}}, + {1, reset} + ]). diff --git a/test/prop_crdt_orset.erl b/test/prop_crdt_orset.erl index 388d07d05..458a0c441 100644 --- a/test/prop_crdt_orset.erl +++ b/test/prop_crdt_orset.erl @@ -39,7 +39,9 @@ add_wins_set_spec(Operations1) -> % such that there is an add operation for X {AddClock, {add, X}} <- Operations, % and there is no remove operation after the add - [] == [Y || {RemoveClock, {remove, Y}} <- Operations, X == Y, crdt_properties:clock_le(AddClock, RemoveClock)] + [] == [Y || {RemoveClock, {remove, Y}} <- Operations, X == Y, crdt_properties:clock_le(AddClock, RemoveClock)], + % and there is no reset operation after the add + [] == [reset || {ResetClock, reset} <- Operations, crdt_properties:clock_le(AddClock, ResetClock)] ]). % transforms add_all and remove_all into single operations @@ -56,7 +58,8 @@ set_op() -> {add, set_element()}, {add_all, list(set_element())}, {remove, set_element()}, - {remove_all, list(set_element())} + {remove_all, list(set_element())}, + reset ]). set_element() -> diff --git a/test/prop_crdt_set_rw.erl b/test/prop_crdt_set_rw.erl index ee66fd0f6..7eb964f1c 100644 --- a/test/prop_crdt_set_rw.erl +++ b/test/prop_crdt_set_rw.erl @@ -33,15 +33,18 @@ prop_orset_spec() -> rem_wins_set_spec(Operations1) -> Operations = lists:flatmap(fun normalizeOperation/1, Operations1), + RemoveClocks = + fun(X) -> + [Clock || {Clock, {remove, Y}} <- Operations, X == Y] + ++ [Clock || {Clock, reset} <- Operations] + end, Removed = - [X || - % such that there is a remove operation for X - {RemClock, {remove, X}} <- Operations, - % and there is no add operation after the remove - [] == [Y || {AddClock, {add, Y}} <- Operations, X == Y, crdt_properties:clock_le(RemClock, AddClock)] - ], - Added = lists:usort([X || {_, {add, X}} <- Operations]), - Added -- Removed. + fun(X) -> + % there is a remove for X which is not followed by an add + lists:any(fun(RemClock) -> [] == [Y || {AddClock, {add, Y}} <- Operations, X == Y, crdt_properties:clock_le(RemClock, AddClock)] end, RemoveClocks(X)) + end, + Added = [X || {_, {add, X}} <- Operations], + [X || X <- lists:usort(Added), not Removed(X)]. % transforms add_all and remove_all into single operations normalizeOperation({Clock, {add_all, Elems}}) -> @@ -57,7 +60,8 @@ set_op() -> {add, set_element()}, {add_all, list(set_element())}, {remove, set_element()}, - {remove_all, list(set_element())} + {remove_all, list(set_element())}, + reset ]). set_element() -> From 442e042e2392995d08749c7c3416c1d3648ed6cd Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Thu, 6 Oct 2016 11:18:19 +0200 Subject: [PATCH 157/426] added batch operation to map --- src/antidote_crdt_map_aw.erl | 36 +++++++++++++++++++++++++++--------- test/prop_crdt_map_aw.erl | 10 ++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/antidote_crdt_map_aw.erl b/src/antidote_crdt_map_aw.erl index 2f92dbb29..02c9f5677 100644 --- a/src/antidote_crdt_map_aw.erl +++ b/src/antidote_crdt_map_aw.erl @@ -46,11 +46,11 @@ | {update, [nested_op()]} | {remove, typedKey()} | {remove, [typedKey()]} + | {batch, {Updates::[nested_op()], Removes::[typedKey()]}} | reset. -type nested_op() :: {typedKey(), Op::term()}. -type effect() :: - {update, [nested_downstream()], AddedToken::token()} - | {remove, [nested_downstream()]}. + {Adds::[nested_downstream()], Removed::[nested_downstream()], AddedToken::token()}. -type nested_downstream() :: {typedKey(), none | {ok, Effect::term()}, RemovedTokens::[token()]}. -spec new() -> state(). @@ -70,12 +70,20 @@ require_state_downstream(_Op) -> downstream({update, {{Key, Type}, Op}}, CurrentMap) -> downstream({update, [{{Key, Type}, Op}]}, CurrentMap); downstream({update, NestedOps}, CurrentMap) -> - Token = unique(), - {ok, {update, [generateDownstreamUpdate(Op, CurrentMap) || Op <- NestedOps], Token}}; + downstream({batch, {NestedOps, []}}, CurrentMap); downstream({remove, {Key, Type}}, CurrentMap) -> downstream({remove, [{Key, Type}]}, CurrentMap); downstream({remove, Keys}, CurrentMap) -> - {ok, {remove, [generateDownstreamRemove(Key, CurrentMap) || Key <- Keys]}}; + downstream({batch, {[], Keys}}, CurrentMap); +downstream({batch, {Updates, Removes}}, CurrentMap) -> + UpdateEffects = [generateDownstreamUpdate(Op, CurrentMap) || Op <- Updates], + RemoveEffects = [generateDownstreamRemove(Key, CurrentMap) || Key <- Removes], + Token = + case UpdateEffects of + [] -> <<>>; % no token required + _ -> unique() + end, + {ok, {UpdateEffects, RemoveEffects, Token}}; downstream(reset, CurrentMap) -> % reset removes all keys AllKeys = [Key || {Key, _Val} <- value(CurrentMap)], @@ -114,10 +122,14 @@ unique() -> crypto:strong_rand_bytes(20). -spec update(effect(), state()) -> {ok, state()}. -update({update, NestedEffects, AddedToken}, State) -> - {ok, lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, NestedEffects)}; -update({remove, NestedEffects}, State) -> - {ok, lists:foldl(fun(E, S) -> update(E, [], S) end, State, NestedEffects)}. +update({Updates, Removes, AddedToken}, State) -> + State2 = lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, Updates), + State3 = lists:foldl(fun(E, S) -> update(E, [], S) end, State2, Removes), + {ok, State3}. +%%update({update, NestedEffects, AddedToken}, State) -> +%% {ok, lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, NestedEffects)}; +%%update({remove, NestedEffects}, State) -> +%% {ok, lists:foldl(fun(E, S) -> update(E, [], S) end, State, NestedEffects)}. update({{Key,Type}, {ok, Op}, RemovedTokens}, NewTokens, Map) -> case dict:find({Key,Type}, Map) of @@ -170,6 +182,12 @@ is_operation(Operation) -> {remove, Keys} when is_list(Keys) -> distinct(Keys) andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Keys); + {batch, {Updates, Removes}} -> + is_list(Updates) + andalso is_list(Removes) + andalso distinct(Removes ++ [Key || {Key, _} <- Updates]) + andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Removes) + andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Updates); reset -> true; _ -> false diff --git a/test/prop_crdt_map_aw.erl b/test/prop_crdt_map_aw.erl index 9130adef0..58cf479d7 100644 --- a/test/prop_crdt_map_aw.erl +++ b/test/prop_crdt_map_aw.erl @@ -63,6 +63,9 @@ normalizeOp({Clock, {update, List}}, _) when is_list(List) -> [{Clock, {update, X}} || X <- List]; normalizeOp({Clock, {remove, List}}, _) when is_list(List) -> [{Clock, {remove, X}} || X <- List]; +normalizeOp({Clock, {batch, {Updates, Removes}}}, _) -> + [{Clock, {update, X}} || X <- Updates] + ++ [{Clock, {remove, X}} || X <- Removes]; normalizeOp({Clock, reset}, Operations) -> % reset is like removing all current keys Map = spec(crdt_properties:subcontext(Clock, Operations)), @@ -79,6 +82,13 @@ op(Size) -> {update, ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, []))}, {remove, typed_key()}, {remove, ?LET(L, list(typed_key()), lists:usort(L))}, + ?LET({Updates,Removes}, + {list(nestedOp(Size div 2)),list(typed_key())}, + begin + Removes2 = lists:usort(Removes), + Updates2 = removeDuplicateKeys(Updates, Removes2), + {batch, {Updates2, Removes2}} + end), reset ]). From 94fc60718a29e122412bd74a24f95ec587450c0f Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Thu, 6 Oct 2016 11:32:21 +0200 Subject: [PATCH 158/426] changed reset operation to follow {atom,param} type --- src/antidote_crdt_gmap.erl | 12 ++++++------ src/antidote_crdt_integer.erl | 8 ++++---- src/antidote_crdt_map_aw.erl | 14 +++++++------- src/antidote_crdt_mvreg.erl | 4 ++-- src/antidote_crdt_orset.erl | 8 ++++---- src/antidote_crdt_set_rw.erl | 12 ++++++------ test/prop_crdt_gmap.erl | 6 +++--- test/prop_crdt_integer.erl | 4 ++-- test/prop_crdt_map_aw.erl | 8 ++++---- test/prop_crdt_mvreg.erl | 4 ++-- test/prop_crdt_orset.erl | 4 ++-- test/prop_crdt_set_rw.erl | 4 ++-- 12 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index aaadc7049..e386b1e95 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -41,7 +41,7 @@ -type gmap_op() :: {update, nested_op()} | {update, [nested_op()]} - | reset. + | {reset, {}}. -type nested_op() :: {{Key::term(), Type::atom() }, Op::term()}. -type gmap_effect() :: {update, nested_downstream()} @@ -72,13 +72,13 @@ downstream({update, {{Key, Type}, Op}}, CurrentMap) -> {ok, {update, {{Key, Type}, DownstreamOp}}}; downstream({update, Ops}, CurrentMap) when is_list(Ops) -> {ok, {update, lists:map(fun(Op) -> {ok, DSOp} = downstream({update, Op}, CurrentMap), DSOp end, Ops)}}; -downstream(reset, CurrentMap) -> +downstream({reset, {}}, CurrentMap) -> % calls reset on all embedded keys which support reset Reset = fun({{Key, Type}, State}) -> - case Type:is_operation(reset) of + case Type:is_operation({reset, {}}) of true -> - {ok, EmbeddedEffect} = Type:downstream(reset, State), + {ok, EmbeddedEffect} = Type:downstream({reset, {}}, State), [{update, {{Key, Type}, EmbeddedEffect}}]; false -> [] end @@ -128,7 +128,7 @@ is_operation(Operation) -> {update, Ops} when is_list(Ops) -> distinct([Key || {Key, _} <- Ops]) andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Ops); - reset -> true; + {reset, {}} -> true; _ -> false end. @@ -157,7 +157,7 @@ update2_test() -> Map1 = new(), {ok, Effect1} = downstream({update,[{{a,antidote_crdt_orset},{add,a}}]}, Map1), {ok, Map2} = update(Effect1, Map1), - {ok, Effect2} = downstream(reset, Map2), + {ok, Effect2} = downstream({reset, {}}, Map2), {ok, Map3} = update(Effect2, Map2), ?assertEqual([{{a, antidote_crdt_orset}, []}], value(Map3)). diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl index 42a701580..175c4ddaa 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/antidote_crdt_integer.erl @@ -46,7 +46,7 @@ -type update() :: {increment, integer()} | {set, integer()} - | reset. + | {reset, {}}. -type effect() :: {increment, integer()} | {set, term(), [term()], integer()}. @@ -67,7 +67,7 @@ downstream({increment, N}, _State) -> downstream({set, N}, {Vals, Delta}) -> Overridden = [Tag || {Tag, _} <- Vals], {ok, {set, unique(), Overridden, N-Delta}}; -downstream(reset, State) -> +downstream({reset, {}}, State) -> % resetting means setting value to 0 downstream({set, 0}, State). @@ -108,13 +108,13 @@ from_binary(Bin) -> -spec is_operation(term()) -> boolean(). is_operation({increment, N}) when is_integer(N) -> true; is_operation({set, N}) when is_integer(N) -> true; -is_operation(reset) -> true; +is_operation({reset, {}}) -> true; is_operation(_) -> false. %% @doc Returns true if ?MODULE:downstream/2 needs the state of crdt %% to generate downstream effect require_state_downstream({set,_}) -> true; -require_state_downstream(reset) -> true; +require_state_downstream({reset, {}}) -> true; require_state_downstream(_) -> false. diff --git a/src/antidote_crdt_map_aw.erl b/src/antidote_crdt_map_aw.erl index 02c9f5677..c90430ca9 100644 --- a/src/antidote_crdt_map_aw.erl +++ b/src/antidote_crdt_map_aw.erl @@ -47,7 +47,7 @@ | {remove, typedKey()} | {remove, [typedKey()]} | {batch, {Updates::[nested_op()], Removes::[typedKey()]}} - | reset. + | {reset, {}}. -type nested_op() :: {typedKey(), Op::term()}. -type effect() :: {Adds::[nested_downstream()], Removed::[nested_downstream()], AddedToken::token()}. @@ -84,7 +84,7 @@ downstream({batch, {Updates, Removes}}, CurrentMap) -> _ -> unique() end, {ok, {UpdateEffects, RemoveEffects, Token}}; -downstream(reset, CurrentMap) -> +downstream({reset, {}}, CurrentMap) -> % reset removes all keys AllKeys = [Key || {Key, _Val} <- value(CurrentMap)], downstream({remove, AllKeys}, CurrentMap). @@ -109,9 +109,9 @@ generateDownstreamRemove({Key,Type}, CurrentMap) -> false -> {[], Type:new()} end, DownstreamEffect = - case Type:is_operation(reset) of + case Type:is_operation({reset, {}}) of true -> - {ok, _} = Type:downstream(reset, CurrentState); + {ok, _} = Type:downstream({reset, {}}, CurrentState); false -> none end, @@ -188,7 +188,7 @@ is_operation(Operation) -> andalso distinct(Removes ++ [Key || {Key, _} <- Updates]) andalso lists:all(fun(Key) -> is_operation({remove, Key}) end, Removes) andalso lists:all(fun(Op) -> is_operation({update, Op}) end, Updates); - reset -> true; + {reset, {}} -> true; _ -> false end. @@ -211,7 +211,7 @@ reset1_test() -> {ok, Incr1} = downstream({update, {{a, antidote_crdt_integer}, {increment, 1}}}, Set0), {ok, Set1a} = update(Incr1, Set0), % DC1 reset - {ok, Reset1} = downstream(reset, Set1a), + {ok, Reset1} = downstream({reset, {}}, Set1a), {ok, Set1b} = update(Reset1, Set1a), % DC2 a.remove {ok, Remove1} = downstream({remove, {a, antidote_crdt_integer}}, Set0), @@ -219,7 +219,7 @@ reset1_test() -> % DC2 --> DC1 {ok, Set1c} = update(Remove1, Set1b), % DC1 reset - {ok, Reset2} = downstream(reset, Set1c), + {ok, Reset2} = downstream({reset, {}}, Set1c), {ok, Set1d} = update(Reset2, Set1c), % DC1: a.incr {ok, Incr2} = downstream({update, {{a, antidote_crdt_integer}, {increment, 0}}}, Set1d), diff --git a/src/antidote_crdt_mvreg.erl b/src/antidote_crdt_mvreg.erl index 9391d9931..01bcd91d4 100644 --- a/src/antidote_crdt_mvreg.erl +++ b/src/antidote_crdt_mvreg.erl @@ -84,7 +84,7 @@ downstream({assign, Value}, MVReg) -> Token = unique(), Overridden = [Tok || {_, Tok} <- MVReg], {ok, {Value, Token, Overridden}}; -downstream(reset, MVReg) -> +downstream({reset, {}}, MVReg) -> Overridden = [Tok || {_, Tok} <- MVReg], {ok, {reset, Overridden}}. @@ -130,7 +130,7 @@ from_binary(<>) -> %% that Operation is supported by this particular CRDT. -spec is_operation(term()) -> boolean(). is_operation({assign, _}) -> true; -is_operation(reset) -> true; +is_operation({reset, {}}) -> true; is_operation(_) -> false. require_state_downstream(_) -> diff --git a/src/antidote_crdt_orset.erl b/src/antidote_crdt_orset.erl index d5f72e1c9..52995511a 100644 --- a/src/antidote_crdt_orset.erl +++ b/src/antidote_crdt_orset.erl @@ -80,7 +80,7 @@ | {remove, member()} | {add_all, [member()]} | {remove_all, [member()]} - | reset. + | {reset, {}}. -type member() :: term(). @@ -137,7 +137,7 @@ downstream({remove_all,Elems}, ORDict) -> Sum++[{Elem, value({tokens, Elem}, ORDict)}] end, [], Elems), {ok, {remove_all, ToRemove}}; -downstream(reset, ORDict) -> +downstream({reset, {}}, ORDict) -> % reset is like removing all elements downstream({remove_all, value(ORDict)}, ORDict). @@ -256,7 +256,7 @@ is_operation({add_all, L}) when is_list(L) -> true; is_operation({remove, _Elem}) -> true; is_operation({remove_all, L}) when is_list(L) -> true; -is_operation(reset) -> true; +is_operation({reset, {}}) -> true; is_operation(_) -> false. require_state_downstream({add,_}) -> @@ -265,7 +265,7 @@ require_state_downstream({add_all,_}) -> false; require_state_downstream({remove,_}) -> true; require_state_downstream({remove_all, _}) -> true; -require_state_downstream(reset) -> true. +require_state_downstream({reset, {}}) -> true. %% =================================================================== %% EUnit tests diff --git a/src/antidote_crdt_set_rw.erl b/src/antidote_crdt_set_rw.erl index e373b63e8..921dee897 100644 --- a/src/antidote_crdt_set_rw.erl +++ b/src/antidote_crdt_set_rw.erl @@ -56,7 +56,7 @@ | {remove, member()} | {add_all, [member()]} | {remove_all, [member()]} - | reset. + | {reset, {}}. -type token() :: term(). -type effect() :: @@ -84,7 +84,7 @@ downstream({remove, Elem}, State) -> downstream({remove_all, [Elem]}, State); downstream({remove_all, Elems}, {ResetTokens, Dict}) -> {ok, {remove, elemsWithRemovedTombstones(lists:usort(Elems), Dict, ResetTokens), unique(), ResetTokens}}; -downstream(reset, {ResetTokens, Dict}) -> +downstream({reset, {}}, {ResetTokens, Dict}) -> RemovedTombstones = elemsWithRemovedTombstones(lists:usort(orddict:fetch_keys(Dict)), Dict, ResetTokens), {ok, {reset, RemovedTombstones, ResetTokens, unique()}}. @@ -157,7 +157,7 @@ is_operation({add_all, L}) when is_list(L) -> true; is_operation({remove, _Elem}) -> true; is_operation({remove_all, L}) when is_list(L) -> true; -is_operation(reset) -> true; +is_operation({reset, {}}) -> true; is_operation(_) -> false. require_state_downstream(_) -> true. @@ -172,7 +172,7 @@ require_state_downstream(_) -> true. reset1_test() -> Set0 = new(), % DC1 reset - {ok, ResetEffect} = downstream(reset, Set0), + {ok, ResetEffect} = downstream({reset, {}}, Set0), {ok, Set1a} = update(ResetEffect, Set0), % DC1 add {ok, Add1Effect} = downstream({add, a}, Set1a), @@ -204,12 +204,12 @@ reset1_test() -> reset2_test() -> Set0 = new(), % DC1 reset - {ok, Reset1Effect} = downstream(reset, Set0), + {ok, Reset1Effect} = downstream({reset, {}}, Set0), {ok, Set1a} = update(Reset1Effect, Set0), % DC1 --> Dc2 {ok, Set2a} = update(Reset1Effect, Set0), % DC2 reset - {ok, Reset2Effect} = downstream(reset, Set2a), + {ok, Reset2Effect} = downstream({reset, {}}, Set2a), {ok, Set2b} = update(Reset2Effect, Set2a), % DC2 add {ok, Add2Effect} = downstream({add, a}, Set2b), diff --git a/test/prop_crdt_gmap.erl b/test/prop_crdt_gmap.erl index 28334dbc0..5c3d5fec7 100644 --- a/test/prop_crdt_gmap.erl +++ b/test/prop_crdt_gmap.erl @@ -40,9 +40,9 @@ spec(Operations1) -> nestedOps(Operations, {_,Type}=Key) -> Resets = - case Type:is_operation(reset) of + case Type:is_operation({reset, {}}) of true -> - [{Clock, reset} || {Clock, reset} <- Operations]; + [{Clock, {reset, {}}} || {Clock, {reset, {}}} <- Operations]; false -> [] end, Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. @@ -66,7 +66,7 @@ op(Size) -> nestedOp(Size), ?LET(L, list(nestedOp(Size div 2)), removeDuplicateKeys(L, [])) ])}}, - {1, reset} + {1, {reset, {}}} ]). removeDuplicateKeys([], _) -> []; diff --git a/test/prop_crdt_integer.erl b/test/prop_crdt_integer.erl index d93006c80..069f44f4f 100644 --- a/test/prop_crdt_integer.erl +++ b/test/prop_crdt_integer.erl @@ -48,7 +48,7 @@ spec(Operations1) -> WithDelta = [Val + Delta(Clock) || {Clock,Val} <- ConcurrentValues2], lists:max(WithDelta). -normalizeOp({Clock, reset}) -> {Clock, {set, 0}}; +normalizeOp({Clock, {reset, {}}}) -> {Clock, {set, 0}}; normalizeOp(Op) -> Op. % generates a random counter operation @@ -56,6 +56,6 @@ op() -> oneof([ {set, integer()}, {increment, integer()}, - reset + {reset, {}} ]). diff --git a/test/prop_crdt_map_aw.erl b/test/prop_crdt_map_aw.erl index 58cf479d7..ed3bb775d 100644 --- a/test/prop_crdt_map_aw.erl +++ b/test/prop_crdt_map_aw.erl @@ -47,9 +47,9 @@ spec(Operations1) -> nestedOps(Operations, {_,Type}=Key) -> Resets = - case Type:is_operation(reset) of + case Type:is_operation({reset, {}}) of true -> - [{Clock, reset} || {Clock, {remove, Key2}} <- Operations, Key == Key2]; + [{Clock, {reset, {}}} || {Clock, {remove, Key2}} <- Operations, Key == Key2]; false -> [] end, Resets ++ [{Clock, NestedOp} || {Clock, {update, {Key2, NestedOp}}} <- Operations, Key == Key2]. @@ -66,7 +66,7 @@ normalizeOp({Clock, {remove, List}}, _) when is_list(List) -> normalizeOp({Clock, {batch, {Updates, Removes}}}, _) -> [{Clock, {update, X}} || X <- Updates] ++ [{Clock, {remove, X}} || X <- Removes]; -normalizeOp({Clock, reset}, Operations) -> +normalizeOp({Clock, {reset, {}}}, Operations) -> % reset is like removing all current keys Map = spec(crdt_properties:subcontext(Clock, Operations)), Keys = [Key || {Key, _Val} <- Map], @@ -89,7 +89,7 @@ op(Size) -> Updates2 = removeDuplicateKeys(Updates, Removes2), {batch, {Updates2, Removes2}} end), - reset + {reset, {}} ]). removeDuplicateKeys([], _) -> []; diff --git a/test/prop_crdt_mvreg.erl b/test/prop_crdt_mvreg.erl index d63a43098..b40d8ef69 100644 --- a/test/prop_crdt_mvreg.erl +++ b/test/prop_crdt_mvreg.erl @@ -37,7 +37,7 @@ spec(Operations) -> % all values, such that not overridden by other assign [] == [Clock2 || {Clock2, {assign, _}} <- Operations, Clock =/= Clock2, crdt_properties:clock_le(Clock, Clock2)], % and not overridden by reset - [] == [Clock3 || {Clock3, reset} <- Operations, crdt_properties:clock_le(Clock, Clock3)] + [] == [Clock3 || {Clock3, {reset, {}}} <- Operations, crdt_properties:clock_le(Clock, Clock3)] ], lists:sort(Values). @@ -47,6 +47,6 @@ spec(Operations) -> op() -> frequency([ {5, {assign, oneof([a,b,c,d,e,f,g,h,i])}}, - {1, reset} + {1, {reset, {}}} ]). diff --git a/test/prop_crdt_orset.erl b/test/prop_crdt_orset.erl index 458a0c441..20994030c 100644 --- a/test/prop_crdt_orset.erl +++ b/test/prop_crdt_orset.erl @@ -41,7 +41,7 @@ add_wins_set_spec(Operations1) -> % and there is no remove operation after the add [] == [Y || {RemoveClock, {remove, Y}} <- Operations, X == Y, crdt_properties:clock_le(AddClock, RemoveClock)], % and there is no reset operation after the add - [] == [reset || {ResetClock, reset} <- Operations, crdt_properties:clock_le(AddClock, ResetClock)] + [] == [{reset, {}} || {ResetClock, {reset, {}}} <- Operations, crdt_properties:clock_le(AddClock, ResetClock)] ]). % transforms add_all and remove_all into single operations @@ -59,7 +59,7 @@ set_op() -> {add_all, list(set_element())}, {remove, set_element()}, {remove_all, list(set_element())}, - reset + {reset, {}} ]). set_element() -> diff --git a/test/prop_crdt_set_rw.erl b/test/prop_crdt_set_rw.erl index 7eb964f1c..e728c916a 100644 --- a/test/prop_crdt_set_rw.erl +++ b/test/prop_crdt_set_rw.erl @@ -36,7 +36,7 @@ rem_wins_set_spec(Operations1) -> RemoveClocks = fun(X) -> [Clock || {Clock, {remove, Y}} <- Operations, X == Y] - ++ [Clock || {Clock, reset} <- Operations] + ++ [Clock || {Clock, {reset, {}}} <- Operations] end, Removed = fun(X) -> @@ -61,7 +61,7 @@ set_op() -> {add_all, list(set_element())}, {remove, set_element()}, {remove_all, list(set_element())}, - reset + {reset, {}} ]). set_element() -> From a83735f72b7f56e0a5fbbb099170b6916d9896f5 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Thu, 6 Oct 2016 17:55:38 +0200 Subject: [PATCH 159/426] added _build to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6770f4b73..2509e2857 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .local_dialyzer_plt deps/ -ebin/ \ No newline at end of file +ebin/ +_build/ From 03ba8b39b0c647b0c0c416cf34714ee0190c3bec Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Thu, 6 Oct 2016 17:55:56 +0200 Subject: [PATCH 160/426] fixed test case for set --- src/antidotec_set.erl | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index b7ddf1f1b..b3e9b8917 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -56,14 +56,9 @@ new() -> #antidote_set{set=sets:new(), adds=sets:new(), rems=sets:new()}. --spec new(list()) -> antidote_set(). -new([]) -> - #antidote_set{set=sets:new(), adds=sets:new(), rems=sets:new()}; - -new([_H | _] = List) -> - Set = lists:foldl(fun(E,S) -> - sets:add_element(E,S) - end,sets:new(),List), +-spec new(list() | sets:set()) -> antidote_set(). +new(List) when is_list(List) -> + Set = sets:from_list(List), #antidote_set{set=Set, adds=sets:new(), rems=sets:new()}; new(Set) -> @@ -72,8 +67,9 @@ new(Set) -> -spec value(antidote_set()) -> [term()]. value(#antidote_set{set=Set}) -> sets:to_list(Set). +-spec dirty_value(antidote_set()) -> [term()]. dirty_value(#antidote_set{set=Set, adds = Adds, rems=Rems}) -> - sets:to_list(sets:subtract(sets:union(Set, Adds), Rems)). + sets:to_list(sets:subtract(sets:union(Set, Adds), Rems)). %% @doc Adds an element to the local set container. -spec add(term(), antidote_set()) -> antidote_set(). @@ -113,20 +109,21 @@ to_ops(BoundObject, #antidote_set{adds=Adds, rems=Rems}) -> %% =================================================================== -ifdef(TEST). add_op_test() -> - New = antidotec_set:new(dumb_key), - EmptySet = sets:size(antidotec_set:dirty_value(New)), - OneElement = antidotec_set:add(atom1,New), - Size1Set = sets:size(antidotec_set:dirty_value(OneElement)), - [?_assert(EmptySet =:= 0), - ?_assert(Size1Set =:= 1)]. + New = antidotec_set:new([]), + Set1 = antidotec_set:dirty_value(New), + ?assertEqual([], Set1), + OneElement = antidotec_set:add(<<"value1">>,New), + Set2 = antidotec_set:dirty_value(OneElement), + ?assertEqual([<<"value1">>], Set2). add_op_existing_set_test() -> - New = antidotec_set:new(dumb_key,[elem1,elem2,elem3]), - ThreeElemSet = sets:size(antidotec_set:dirty_value(New)), - AddElem = antidotec_set:add(elem4,New), - S1 = antidotec_set:remove(elem4,AddElem), - S2 = antidotec_set:remove(elem2,S1), - TwoElemSet = sets:size(antidotec_set:dirty_value(S2)), - [?_assert(ThreeElemSet =:= 3), - ?_assert(TwoElemSet =:= 2)]. + New = antidotec_set:new([<<"elem1">>,<<"elem2">>,<<"elem3">>]), + ThreeElemSet = antidotec_set:dirty_value(New), + ?assertEqual([<<"elem1">>, <<"elem2">>, <<"elem3">>], ThreeElemSet), + AddElem = antidotec_set:add(<<"elem4">>,New), + S1 = antidotec_set:remove(<<"elem4">>,AddElem), + S2 = antidotec_set:remove(<<"elem2">>,S1), + TwoElemSet = antidotec_set:dirty_value(S2), + ?assertEqual([<<"elem1">>, <<"elem3">>], TwoElemSet). + -endif. From 77d471c74b31e1e242b7bc6407988753f4e1b768 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 7 Oct 2016 09:47:50 +0200 Subject: [PATCH 161/426] fixed order in test --- src/antidotec_set.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/antidotec_set.erl b/src/antidotec_set.erl index b3e9b8917..6744a46f7 100644 --- a/src/antidotec_set.erl +++ b/src/antidotec_set.erl @@ -119,11 +119,11 @@ add_op_test() -> add_op_existing_set_test() -> New = antidotec_set:new([<<"elem1">>,<<"elem2">>,<<"elem3">>]), ThreeElemSet = antidotec_set:dirty_value(New), - ?assertEqual([<<"elem1">>, <<"elem2">>, <<"elem3">>], ThreeElemSet), + ?assertEqual([<<"elem1">>, <<"elem2">>, <<"elem3">>], lists:sort(ThreeElemSet)), AddElem = antidotec_set:add(<<"elem4">>,New), S1 = antidotec_set:remove(<<"elem4">>,AddElem), S2 = antidotec_set:remove(<<"elem2">>,S1), TwoElemSet = antidotec_set:dirty_value(S2), - ?assertEqual([<<"elem1">>, <<"elem3">>], TwoElemSet). + ?assertEqual([<<"elem1">>, <<"elem3">>], lists:sort(TwoElemSet)). -endif. From e1fd78f8929661d43c4b62dd3fe36c043138caa2 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 7 Oct 2016 09:48:04 +0200 Subject: [PATCH 162/426] use pb library with new types --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 705284b4b..1e343c903 100644 --- a/rebar.config +++ b/rebar.config @@ -3,7 +3,7 @@ {deps, [ {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "3.2.1"}}}, - {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {branch, "antidote_crdt_rebar3"}}} + {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {branch, "antidote_pb_new_crdts"}}} ]}. {plugins, [ From db1afc909db8b43f64b04127d44f2e0c2a0a9752 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 7 Oct 2016 10:05:51 +0200 Subject: [PATCH 163/426] add read_values function for when you don't want to use the wrapper-objects --- src/antidotec_pb.erl | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index 242f24bef..d80f496be 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -23,10 +23,10 @@ -export([start_transaction/3, - abort_transaction/2, - commit_transaction/2, - update_objects/3, - read_objects/3]). + abort_transaction/2, + commit_transaction/2, + update_objects/3, + read_objects/3, read_values/3]). -define(TIMEOUT, 10000). @@ -157,7 +157,38 @@ read_objects(Pid, Objects, {static, TxId}) -> {error, Reason} -> {error, Reason} end end. - + +-spec read_values(Pid::term(), Objects::[term()], TxId::term()) -> {ok, [term()]} | {error, term()}. +read_values(Pid, Objects, {interactive, TxId}) -> + EncMsg = antidote_pb_codec:encode(read_objects, {Objects, TxId}), + Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {read_objects, Values} -> + {ok, Values}; + {error, Reason} -> {error, Reason}; + Other -> {error, Other} + end + end; +read_values(Pid, Objects, {static, TxId}) -> + {Clock, Properties} = TxId, + EncMsg = antidote_pb_codec:encode(static_read_objects, + {Clock, Properties, Objects}), + Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), + case Result of + {error, timeout} -> {error, timeout}; + _ -> + case antidote_pb_codec:decode_response(Result) of + {static_read_objects_resp, Values, CommitTimeStamp} -> + antidotec_pb_socket:store_commit_time(Pid, CommitTimeStamp), + {ok, Values}; + {error, Reason} -> {error, Reason} + end + end. + + is_static(TxnProperties) -> case TxnProperties of [{static, true}] -> From 8b7afa62ac29496d376914ffc8025c8c10086e51 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 7 Oct 2016 18:57:45 +0200 Subject: [PATCH 164/426] added documentation --- src/antidote_crdt_gmap.erl | 1 + src/antidote_crdt_integer.erl | 13 +++++++++++-- src/antidote_crdt_map_aw.erl | 16 ++++++++++------ src/antidote_crdt_set_rw.erl | 15 +++++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/antidote_crdt_gmap.erl b/src/antidote_crdt_gmap.erl index e386b1e95..0f7577079 100644 --- a/src/antidote_crdt_gmap.erl +++ b/src/antidote_crdt_gmap.erl @@ -23,6 +23,7 @@ %% This map simply forwards all operations to the embedded CRDTs. %% There is no real remove-operation. %% +%% The reset operation, forwards the reset to all values in the map. -module(antidote_crdt_gmap). diff --git a/src/antidote_crdt_integer.erl b/src/antidote_crdt_integer.erl index 175c4ddaa..39fcbbc5c 100644 --- a/src/antidote_crdt_integer.erl +++ b/src/antidote_crdt_integer.erl @@ -18,10 +18,19 @@ %% %% ------------------------------------------------------------------- -%% antidote_crdt_integer: A convergent, replicated, operation -%% based integer +%% antidote_crdt_integer: A convergent, replicated, operation based integer %% +%% This is an extension of the counter: +%% Besides the increment operation, it also provides a set operation %% +%% Semantics: +%% The value of the counter is determines as follows: +%% 1) as base-values take the value of the latest (concurrent) set-operations (or 0 if there are none) +%% 2) for each base-value: add the increments which are concurrent to or after the respective set and add them to the base value +%% 3) take the maximum of these values (note that this is not always the maximum base-value) +%% +%% Implementation: +%% A mix of counter and mvreg -module(antidote_crdt_integer). diff --git a/src/antidote_crdt_map_aw.erl b/src/antidote_crdt_map_aw.erl index c90430ca9..7ddc6ac74 100644 --- a/src/antidote_crdt_map_aw.erl +++ b/src/antidote_crdt_map_aw.erl @@ -24,6 +24,16 @@ %% Deleting a key tries to reset the entry to its initial state %% %% An element exists in a map, if there is at least one update on the key, which is not followed by a remove +%% +%% Resetting the map means removing all the current entries +%% +%% Implementation note: +%% The implementation of Add-wins semantic is the same as in orset: +%% Each element has a set of add-tokens. +%% An entry is in the map, if the set of add-tokens is not empty. +%% When an entry is removed, the value is still kept in the state, so that +%% concurrent updates can be reconciled. +%% This could be optimized for certain types -module(antidote_crdt_map_aw). @@ -126,10 +136,6 @@ update({Updates, Removes, AddedToken}, State) -> State2 = lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, Updates), State3 = lists:foldl(fun(E, S) -> update(E, [], S) end, State2, Removes), {ok, State3}. -%%update({update, NestedEffects, AddedToken}, State) -> -%% {ok, lists:foldl(fun(E, S) -> update(E, [AddedToken], S) end, State, NestedEffects)}; -%%update({remove, NestedEffects}, State) -> -%% {ok, lists:foldl(fun(E, S) -> update(E, [], S) end, State, NestedEffects)}. update({{Key,Type}, {ok, Op}, RemovedTokens}, NewTokens, Map) -> case dict:find({Key,Type}, Map) of @@ -162,11 +168,9 @@ equal(Map1, Map2) -> -define(V1_VERS, 1). to_binary(Policy) -> - %% @TODO okthing smarter <>. from_binary(<>) -> - %% @TODO okthing smarter {ok, binary_to_term(Bin)}. is_operation(Operation) -> diff --git a/src/antidote_crdt_set_rw.erl b/src/antidote_crdt_set_rw.erl index 921dee897..dd04a927f 100644 --- a/src/antidote_crdt_set_rw.erl +++ b/src/antidote_crdt_set_rw.erl @@ -23,6 +23,21 @@ %% @doc %% An operation-based Remove-wins Set CRDT. %% +%% Semantics: +%% Add-operations only affect the remove-operations, which they have observed. +%% The concurrent remove-operations will win over an add-operation. +%% A reset operation has the same effect as removing all possible elements (not only the ones currently in the set). +%% +%% Implementation: +%% The implementation is not very efficient, in particular tombstones for removed elements are stored forever. +%% +%% The state is a pair of: +%% a) the reset tokens, which store when the last resets were executed +%% b) a mapping from elements to a set of tombstone-tokens +%% +%% An element is in the set, if its set of tombstone-tokens is empty. +%% An add-operation will remove the current tombstones of an element. + %% @end -module(antidote_crdt_set_rw). From 70d25b7f6e865203faf72b41959ec1deed6d04b7 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Fri, 7 Oct 2016 20:03:04 +0200 Subject: [PATCH 165/426] share code between read_objects and read_values --- src/antidotec_pb.erl | 56 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/src/antidotec_pb.erl b/src/antidotec_pb.erl index d80f496be..599020a11 100644 --- a/src/antidotec_pb.erl +++ b/src/antidotec_pb.erl @@ -23,10 +23,11 @@ -export([start_transaction/3, - abort_transaction/2, - commit_transaction/2, - update_objects/3, - read_objects/3, read_values/3]). + abort_transaction/2, + commit_transaction/2, + update_objects/3, + read_objects/3, + read_values/3]). -define(TIMEOUT, 10000). @@ -120,42 +121,17 @@ update_objects(Pid, Updates, {static, TxId}) -> end. -spec read_objects(Pid::term(), Objects::[term()], TxId::term()) -> {ok, [term()]} | {error, term()}. -read_objects(Pid, Objects, {interactive, TxId}) -> - EncMsg = antidote_pb_codec:encode(read_objects, {Objects, TxId}), - Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), - case Result of - {error, timeout} -> {error, timeout}; - _ -> - case antidote_pb_codec:decode_response(Result) of - {read_objects, Values} -> - ResObjects = lists:map(fun({Type, Val}) -> - Mod = antidotec_datatype:module_for_type(Type), - Mod:new(Val) - end, Values), - {ok, ResObjects}; - {error, Reason} -> {error, Reason}; - Other -> {error, Other} - end - end; -read_objects(Pid, Objects, {static, TxId}) -> - {Clock, Properties} = TxId, - EncMsg = antidote_pb_codec:encode(static_read_objects, - {Clock, Properties, Objects}), - Result = antidotec_pb_socket:call_infinity(Pid, {req, EncMsg, ?TIMEOUT}), - case Result of - {error, timeout} -> {error, timeout}; - _ -> - case antidote_pb_codec:decode_response(Result) of - {static_read_objects_resp, Values, CommitTimeStamp} -> - antidotec_pb_socket:store_commit_time(Pid, CommitTimeStamp), - ResObjects = lists:map( - fun({Type, Val}) -> - Mod = antidotec_datatype:module_for_type(Type), - Mod:new(Val) - end, Values), - {ok, ResObjects}; - {error, Reason} -> {error, Reason} - end +read_objects(Pid, Objects, Transaction) -> + case read_values(Pid, Objects, Transaction) of + {ok, Values} -> + ResObjects = lists:map( + fun({Type, Val}) -> + Mod = antidotec_datatype:module_for_type(Type), + Mod:new(Val) + end, Values), + {ok, ResObjects}; + Other -> + Other end. -spec read_values(Pid::term(), Objects::[term()], TxId::term()) -> {ok, [term()]} | {error, term()}. From 69679e9b9f881fe95f496c605c9cb7d3d52f22b9 Mon Sep 17 00:00:00 2001 From: Peter Zeller Date: Mon, 10 Oct 2016 18:02:22 +0200 Subject: [PATCH 166/426] updated riak_pb dependency --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 1e343c903..f3d922306 100644 --- a/rebar.config +++ b/rebar.config @@ -3,7 +3,7 @@ {deps, [ {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "3.2.1"}}}, - {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {branch, "antidote_pb_new_crdts"}}} + {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {tag, "v0.2.0"}}} ]}. {plugins, [ From 8942049cbb116ad7a92cbaac798b61801aaa1513 Mon Sep 17 00:00:00 2001 From: Alejandro Zlatko Tomsic Date: Tue, 18 Oct 2016 11:56:32 +0200 Subject: [PATCH 167/426] Update rebar.config removed 2.0 tag --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index f3d922306..792fe9f7d 100644 --- a/rebar.config +++ b/rebar.config @@ -2,7 +2,7 @@ {sub_dirs, ["rel"]}. {deps, [ - {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "3.2.1"}}}, + {lager, {git, "https://github.com/basho/lager", {tag, "3.2.1"}}}, {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {tag, "v0.2.0"}}} ]}. From 08780e1e2b76ac788401c63c45e39a445a363d7d Mon Sep 17 00:00:00 2001 From: Alejandro Zlatko Tomsic Date: Tue, 18 Oct 2016 12:16:13 +0200 Subject: [PATCH 168/426] Update rebar.config reverted unnecessary change. --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 792fe9f7d..f3d922306 100644 --- a/rebar.config +++ b/rebar.config @@ -2,7 +2,7 @@ {sub_dirs, ["rel"]}. {deps, [ - {lager, {git, "https://github.com/basho/lager", {tag, "3.2.1"}}}, + {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "3.2.1"}}}, {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {tag, "v0.2.0"}}} ]}. From 780176c3f6a11789fc7e6a36e1d7312da8232014 Mon Sep 17 00:00:00 2001 From: Alejandro Zlatko Tomsic Date: Tue, 18 Oct 2016 12:56:11 +0200 Subject: [PATCH 169/426] Update rebar.config add compatibility with erlang19 --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index f3d922306..792fe9f7d 100644 --- a/rebar.config +++ b/rebar.config @@ -2,7 +2,7 @@ {sub_dirs, ["rel"]}. {deps, [ - {lager, "2.0", {git, "git://github.com/basho/lager", {tag, "3.2.1"}}}, + {lager, {git, "https://github.com/basho/lager", {tag, "3.2.1"}}}, {riak_pb, ".*", {git, "git://github.com/syncfree/riak_pb", {tag, "v0.2.0"}}} ]}. From eb59f91ec8fa111dbbb50e399c181d1ab57bcb96 Mon Sep 17 00:00:00 2001 From: Christopher Meiklejohn Date: Tue, 18 Oct 2016 11:21:01 -0700 Subject: [PATCH 170/426] Convert to rebar3. --- Makefile | 14 +++++--------- rebar.lock | 20 ++++++++++++++++++++ rebar3 | Bin 0 -> 730312 bytes 3 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 rebar.lock create mode 100755 rebar3 diff --git a/Makefile b/Makefile index 142ec4d57..cb578a9d4 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,17 @@ +REBAR := ./rebar3 + .PHONY: rel deps test all: deps compile compile: deps - @./rebar compile - -app: - @./rebar compile skip_deps=true + @${REBAR} compile deps: - @./rebar get-deps + @${REBAR} deps clean: - @./rebar clean - -distclean: clean - @./rebar delete-deps + @${REBAR} clean DIALYZER_APPS = kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \ xmerl webtool eunit syntax_tools compiler mnesia public_key snmp diff --git a/rebar.lock b/rebar.lock new file mode 100644 index 000000000..35817bfca --- /dev/null +++ b/rebar.lock @@ -0,0 +1,20 @@ +[{<<"goldrush">>, + {git,"git://github.com/DeadZen/goldrush.git", + {ref,"212299233c7e7eb63a97be2777e1c05ebaa58dbe"}}, + 1}, + {<<"lager">>, + {git,"https://github.com/basho/lager", + {ref,"8187757388c9adc915379caaab36a2f2ca26e944"}}, + 0}, + {<<"meck">>, + {git,"https://github.com/basho/meck.git", + {ref,"dde759050eff19a1a80fd854d7375174b191665d"}}, + 2}, + {<<"protobuffs">>, + {git,"git://github.com/basho/erlang_protobuffs.git", + {ref,"0dde9d3b37b7bec3a4dfb0e87684dd7039e169ab"}}, + 1}, + {<<"riak_pb">>, + {git,"git://github.com/syncfree/riak_pb", + {ref,"322309b2bb69b38191a51b21247a71b5e412e656"}}, + 0}]. diff --git a/rebar3 b/rebar3 new file mode 100755 index 0000000000000000000000000000000000000000..93089c66b3a0d676353b4ae898e4ebc9fe987ee5 GIT binary patch literal 730312 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 z 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%0DRW(+W1#A4ItE;C1=}{nZDntJP(({yE{$eBf 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⪫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

bn3yPN_&9?t|DjI6 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ⅈZGe<8Ae?jjWGFrUs-hSZjl18j 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

Sab@dco=9 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