Permalink
Browse files

clock mismatch edge cases?

  • Loading branch information...
etrepum committed Jun 15, 2011
1 parent a9e1b9e commit 373f4aed27dba1e640cd0ac82bab00df8e9cba30
Showing with 44 additions and 3 deletions.
  1. +11 −3 src/statebox_counter.erl
  2. +33 −0 test/statebox_counter_tests.erl
View
@@ -1,6 +1,7 @@
%% @doc Integer counter based on an ordered list of events.
-module(statebox_counter).
--export([value/1, merge/1, compact/2, inc/3, f_inc_compact/2, op_inc_compact/4]).
+-export([value/1, merge/1, compact/2, inc/3]).
+-export([f_inc_compact/2, f_inc_compact/3, op_inc_compact/4]).
-type op() :: statebox:op().
-type timestamp() :: statebox_clock:timestamp().
@@ -23,17 +24,24 @@ merge(Counters) ->
orddict:from_list(lists:umerge(compact_heads(Counters))).
-spec compact(timestamp(), counter()) -> counter().
+compact(Timestamp, Counter=[{T0, merged} | _]) when Timestamp =< T0 ->
+ Counter;
compact(Timestamp, Counter) ->
compact(Timestamp, Counter, 0).
-spec inc(counter_key(), integer(), counter()) -> counter().
+inc({T1, _Id1}, _Value, Counter=[{T0, merged} | _Rest]) when T1 =< T0 ->
+ Counter;
inc(Key, Value, Counter) ->
orddict:store(Key, Value, Counter).
-spec f_inc_compact(integer(), timedelta()) -> op().
f_inc_compact(Value, Age) ->
- Timestamp = statebox_clock:timestamp(),
- Key = {Timestamp, statebox_identity:entropy()},
+ Key = {statebox_clock:timestamp(), statebox_identity:entropy()},
+ f_inc_compact(Value, Age, Key).
+
+-spec f_inc_compact(integer(), timedelta(), counter_key()) -> op().
+f_inc_compact(Value, Age, Key={Timestamp, _Id}) ->
{fun ?MODULE:op_inc_compact/4, [Timestamp - Age, Key, Value]}.
%% @private
@@ -61,6 +61,39 @@ initial_test() ->
statebox_counter:value([])),
ok.
+inc_test() ->
+ C0 = [],
+ C1 = statebox_counter:inc({1, 1}, 1, C0),
+ C2 = statebox_counter:inc({2, 2}, 1, C1),
+ ?assertEqual(
+ 0,
+ statebox_counter:value(C0)),
+ ?assertEqual(
+ 1,
+ statebox_counter:value(C1)),
+ ?assertEqual(
+ 2,
+ statebox_counter:value(C2)),
+ ok.
+
+merge_test() ->
+ C0 = [],
+ C1 = statebox_counter:inc({1, 1}, 1, C0),
+ C2 = statebox_counter:inc({2, 2}, 1, C1),
+ ?assertEqual(
+ 2,
+ statebox_counter:value(statebox_counter:merge([C0, C1, C2]))),
+ ?assertEqual(
+ 1,
+ statebox_counter:value(statebox_counter:merge([C0, C1, C1]))),
+ ?assertEqual(
+ 1,
+ statebox_counter:value(statebox_counter:merge([C1]))),
+ ?assertEqual(
+ 0,
+ statebox_counter:value(statebox_counter:merge([C0, C0]))),
+ ok.
+
next_clock(N) ->
Next = N + clock_step(),
meck:expect(statebox_clock, timestamp, fun () -> next_clock(Next) end),

0 comments on commit 373f4ae

Please sign in to comment.