This repository has been archived by the owner on May 27, 2022. It is now read-only.
forked from deepthidevaki/antidote_crdt
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from peterzeller/improved-types
Improved interface for dialyzer
- Loading branch information
Showing
3 changed files
with
194 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,98 @@ | ||
# Antidote CRDT library | ||
# Antidote CRDT library | ||
[![Build Status](https://travis-ci.org/SyncFree/antidote_crdt.svg?branch=master)](https://travis-ci.org/SyncFree/antidote_crdt) | ||
|
||
CRDT implementations to use with Antidote. | ||
Operation based CRDT implementations to use with Antidote. | ||
|
||
# API | ||
|
||
The `antidote_crdt` module provides the API below. | ||
For a more detailed description of the different data types, the [Antidote Documentation](http://syncfree.github.io/antidote/crdts.html) provides more information. | ||
|
||
```erlang | ||
% The CRDTs supported by Antidote: | ||
-type typ() :: | ||
antidote_crdt_counter_pn % PN-Counter aka Positive Negative Counter | ||
| antidote_crdt_counter_b % Bounded Counter | ||
| antidote_crdt_counter_fat % Fat Counter | ||
| antidote_crdt_flag_ew % Enable Wins Flag aka EW-Flag | ||
| antidote_crdt_flag_dw % Disable Wins Flag DW-Flag | ||
| antidote_crdt_set_go % Grow Only Set aka G-Set | ||
| antidote_crdt_set_aw % Add Wins Set aka AW-Set | ||
| antidote_crdt_set_rw % Remove Wins Set aka RW-Set | ||
| antidote_crdt_register_lww % Last Writer Wins Register aka LWW-Reg | ||
| antidote_crdt_register_mv % MultiValue Register aka MV-Reg | ||
| antidote_crdt_map_go % Grow Only Map aka G-Map | ||
| antidote_crdt_map_rr. % Recursive Resets Map aka RR-Map | ||
|
||
% Note: the crdt and effect types are not correct, the tags just help to find errors | ||
% The State of a CRDT: | ||
-opaque crdt() :: ... | ||
% The downstream effect, which has to be applied at each replica | ||
-opaque effect() :: ... | ||
% The update operation, consisting of operation name and parameters | ||
% (e.g. {increment, 1} to increment a counter by one) | ||
-type update() :: {atom(), term()}. | ||
% Result of reading a CRDT (state without meta data) | ||
-type value() :: term(). | ||
``` | ||
|
||
```erlang | ||
% Check if the given type is supported by Antidote | ||
-spec is_type(typ()) -> boolean(). | ||
|
||
% Returns the initial CRDT state for the given Type | ||
-spec new(typ()) -> crdt(). | ||
|
||
% Reads the value from a CRDT state | ||
-spec value(typ(), crdt()) -> any(). | ||
|
||
% Computes the downstream effect for a given update operation and current state. | ||
% This has to be called once at the source replica. | ||
% The effect must then be applied on all replicas using the update function. | ||
% For some update operation it is not necessary to provide the current state | ||
% and the atom 'ignore' can be passed instead (see function require_state_downstream). | ||
-spec downstream(typ(), update(), crdt() | ignore) -> {ok, effect()} | {error, reason()}. | ||
|
||
% Updates the state of a CRDT by applying a downstream effect calculated | ||
% using the downstream function. | ||
% For most types the update function must be called in causal order: | ||
% if Eff2 was calculated on a state where Eff1 was already replied, | ||
% then Eff1 has to be applied before Eff2 on all replicas. | ||
-spec update(typ(), effect(), crdt()) -> {ok, crdt()}. | ||
|
||
% Checks whether the current state is required by the downstream function | ||
% for a specific type and update operation | ||
-spec require_state_downstream(typ(), update()) -> boolean(). | ||
|
||
% Checks whether the given update operation is valid for the given type | ||
-spec is_operation(typ(), update()) -> boolean(). | ||
``` | ||
|
||
# Development | ||
|
||
Use the following `make` targets to build and test the CRDT library: | ||
|
||
|
||
# compile | ||
make compile | ||
# run unit tests: | ||
make test | ||
# check types: | ||
make dialyzer | ||
# check code style: | ||
make lint | ||
# compile | ||
make compile | ||
# run unit tests: | ||
make test | ||
# check types: | ||
make dialyzer | ||
# check code style: | ||
make lint | ||
|
||
|
||
## PropEr tests | ||
|
||
To run the property based tests in the test directory install the [rebar3 PropEr plugin](https://www.rebar3.org/docs/using-available-plugins#proper) by adding the following line to `~/.config/rebar3/rebar.config`: | ||
|
||
{plugins, [rebar3_proper]}. | ||
{plugins, [{rebar3_proper, "0.9.0"}]}. | ||
|
||
Then execute the tests with: | ||
|
||
make proper | ||
make proper | ||
|
||
For more control, you can run PropEr manually and specify parameters like the tested module or the number of generated tests: | ||
|
||
rebar3 proper -n 1000 -m prop_crdt_orset | ||
rebar3 proper -n 1000 -m prop_crdt_orset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters