-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First pass at implementing a wrapper library.
Manually stub out the term_to_natural and natural_to_term functions for the time being, because the actual implementation is most likely not going to scale.
- Loading branch information
1 parent
db71176
commit 1d2dd68
Showing
1 changed file
with
141 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
%% @doc Provide a wrapper library which provides the same interface | ||
%% as riak_core's vclock library, but uses the vvclock library to | ||
%% support use of the verified version. | ||
%% | ||
%% Manually stub out the natural/term conversion calls for the time | ||
%% being to optimize for testing the library with the current test | ||
%% suite. | ||
%% | ||
|
||
-module(vclock). | ||
|
||
-export([fresh/0, | ||
descends/2, | ||
merge/1, | ||
get_counter/2, | ||
get_timestamp/2, | ||
increment/2, | ||
increment/3, | ||
all_nodes/1, | ||
equal/2, | ||
prune/3, | ||
timestamp/0]). | ||
|
||
%% @doc Return natural timestamp. | ||
timestamp() -> | ||
calendar:datetime_to_gregorian_seconds(erlang:universaltime()). | ||
|
||
%% @doc Generate a fresh vector clock. | ||
fresh() -> | ||
vvclock:fresh(). | ||
|
||
%% @doc Increment a vector clock for a particular actor. | ||
increment(Actor, VClock) -> | ||
vvclock:increment(term_to_peano(Actor), VClock). | ||
|
||
%% @doc Increment a vector clock with a particular timestamp. | ||
increment(_Actor, _Timestamp, _VClock) -> | ||
%% Not implementing this one for now. | ||
erlang:error(deprecated). | ||
|
||
%% @doc Return counter for a particular actor. | ||
get_counter(Actor, VClock) -> | ||
Counter = vvclock:get_counter(term_to_peano(Actor), VClock), | ||
peano_to_term(Counter). | ||
|
||
%% @doc Return timestamp for a particular actor. | ||
get_timestamp(Actor, VClock) -> | ||
Timestamp = vvclock:get_timestamp(term_to_peano(Actor), VClock), | ||
peano_to_term(Timestamp). | ||
|
||
%% @doc Determine if one vector clock is an ancestor of another. | ||
descends(VClock1, VClock2) -> | ||
case vvclock:descends(VClock1, VClock2) of | ||
'True' -> | ||
true; | ||
'False' -> | ||
false | ||
end. | ||
|
||
%% @doc Return list of all actors that have ever touched the vclock. | ||
all_nodes(VClock) -> | ||
[peano_to_term(Node) || Node <- vvclock:all_nodes(VClock)]. | ||
|
||
%% @doc Prune vclocks. | ||
prune(VClock, _Timestamp, BProps) -> | ||
Old = get_property(old_vclock, BProps), | ||
Young = get_property(young_vclock, BProps), | ||
Large = get_property(large_vclock, BProps), | ||
Small = get_property(small_vclock, BProps), | ||
vvclock:prune(VClock, Small, Large, Young, Old). | ||
|
||
%% @doc Merge function which operates on a list of vector clocks. | ||
merge([VClock1,VClock2|VClocks]) -> | ||
merge([vvclock:merge(VClock1, VClock2)|VClocks]); | ||
merge([VClock]) -> | ||
VClock; | ||
merge([]) -> | ||
[]. | ||
|
||
%% @doc Compare equality of two vclocks. | ||
equal(VClock1, VClock2) -> | ||
vvclock:equal(VClock1, VClock2). | ||
|
||
%% @doc Convert a peano number back into an erlang term. | ||
peano_to_term(Peano) -> | ||
natural_to_term(peano_to_natural(Peano)). | ||
|
||
%% @doc Convert an erlang term into a peano number. | ||
term_to_peano(Term) -> | ||
natural_to_peano(term_to_natural(Term)). | ||
|
||
%% @doc Convert a natural number to an erlang term. | ||
natural_to_term(Natural) -> | ||
case Natural of | ||
1 -> | ||
a; | ||
2 -> | ||
b; | ||
3 -> | ||
c; | ||
4 -> | ||
d; | ||
_ -> | ||
erlang:error(not_supported) | ||
end. | ||
|
||
%% @doc Convert an erlang term to a natural number. | ||
term_to_natural(Term) -> | ||
case Term of | ||
a -> | ||
1; | ||
b -> | ||
2; | ||
c -> | ||
3; | ||
d -> | ||
4; | ||
_ -> | ||
erlang:error(not_supported) | ||
end. | ||
|
||
%% @doc Convert a natural number into a peano. | ||
natural_to_peano(0) -> | ||
'O'; | ||
natural_to_peano(Natural) -> | ||
{'S', natural_to_peano(Natural - 1)}. | ||
|
||
%% @doc Convert a peano number into a natural. | ||
peano_to_natural('O') -> | ||
0; | ||
peano_to_natural({'S', Peano}) -> | ||
1 + Peano. | ||
|
||
%% @doc Extract property from bucket properties. | ||
get_property(Key, PairList) -> | ||
case lists:keyfind(Key, 1, PairList) of | ||
{_Key, Value} -> | ||
Value; | ||
false -> | ||
undefined | ||
end. |