Behaviours: riak_dt.
References
http://hal.upmc.fr/inria-00555588/
http://arxiv.org/abs/1210.3368
http://arxiv.org/abs/1011.5808
See also: riak_dt_multi, riak_dt_vclock.
An OR-Set CRDT. An OR-Set allows the adding, and removal, of
elements. Should an add and remove be concurrent, the add wins. In
this implementation there is a version vector for the whole set.
When an element is added to the set, the version vector is
incremented and the {actor(), count()} pair for that increment is
stored against the element as its "birth dot". Every time the
element is re-added to the set, its "birth dot" is updated to that
of the {actor(), count()} version vector entry resulting from the
add. When an element is removed, we simply drop it, no tombstones.
When an element exists in replica A and not replica B, is it because A added it and B has not yet seen that, or that B removed it and A has not yet seen that? Usually the presence of a tombstone arbitrates. In this implementation we compare the "birth dot" of the present element to the clock in the Set it is absent from. If the element dot is not "seen" by the Set clock, that means the other set has yet to see this add, and the item is in the merged Set. If the Set clock dominates the dot, that means the other Set has removed this element already, and the item is not in the merged Set.
Essentially we've made a dotted version vector.actor() = riak_dt:actor()
any_orswot() = v2_orswot() | v2ord_orswot()
binary_orswot() = binary()
A binary that from_binary/1 will operate on.
deferred() = dict(riak_dt_vclock:vclock(), [member()])
dict(_A, _B) = dict()
dot() = riak_dt:dot()
dots() = [dot()]
entries() = dict(member(), dots())
member() = term()
orswot() = v1_orswot() | v2_orswot()
orswot_op() = {add, member()} | {remove, member()} | {add_all, [member()]} | {remove_all, [member()]} | {update, [orswot_op()]}
orswot_q() = size | {contains, term()}
precondition_error() = {error, {precondition, {not_present, member()}}}
v1_orswot() = {riak_dt_vclock:vclock(), {member(), dots()}, {riak_dt_vclock:vclock(), [member()]}}
v2_orswot() = {riak_dt_vclock:vclock(), entries(), deferred()}
v2ord_orswot() = {riak_dt_vclock:vclock(), orddict:orddict(), orddict:orddict()}
| equal/2 | |
| from_binary/1 | When the argument is a binary_orswot() produced by
to_binary/1 will return the original orswot(). |
| merge/2 | |
| new/0 | |
| parent_clock/2 | sets the clock in the Set to that Clock. |
| precondition_context/1 | the precondition context is a fragment of the CRDT that operations requiring certain pre-conditions can be applied with. |
| stat/2 | |
| stats/1 | |
| to_binary/1 | returns a binary representation of the provided
orswot(). |
| to_version/2 | |
| update/3 | take a list of Set operations and apply them to the set. |
| update/4 | |
| value/1 | |
| value/2 |
from_binary(B::binary_orswot()) -> {ok, orswot()} | {error, unsupported_version, Vers::pos_integer()} | {error, invalid_binary}
When the argument is a binary_orswot() produced by
to_binary/1 will return the original orswot().
See also: to_binary/1.
new() -> orswot()
parent_clock(Clock::riak_dt_vclock:vclock(), Set::orswot()) -> orswot()
sets the clock in the Set to that Clock. Used by a
containing Map for sub-CRDTs
the precondition context is a fragment of the CRDT that
operations requiring certain pre-conditions can be applied with.
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. In the case of the ORSWOT the context is a
version vector. When passed as an argument to update/4 the
context ensures that only seen adds are removed, and that removes
of unseen adds can be deferred until they're seen.
stat(Stat::atom(), S::orswot()) -> number() | undefined
stats(ORSWOT::orswot()) -> [{atom(), number()}]
to_binary(S::orswot()) -> binary_orswot()
returns a binary representation of the provided
orswot(). The resulting binary is tagged and versioned for ease
of future upgrade. Calling from_binary/1 with the result of this
function will return the original set. Use the application env var
binary_compression to turn t2b compression on (true) and off
(false)
See also: from_binary/1.
to_version(X1::pos_integer(), Set::any_orswot()) -> any_orswot()
update(Op::orswot_op(), Actor::actor() | dot(), V1Set::orswot()) -> {ok, orswot()} | precondition_error()
take a list of Set operations and apply them to the set. NOTE: either _all_ are applied, or _none_ are.
update(Op::orswot_op(), Actor::actor() | dot(), V1Set::orswot(), Ctx::riak_dt:context()) -> {ok, orswot()} | precondition_error()
value(X1::orswot_q(), ORset::orswot()) -> term()
Generated by EDoc