add unit test for async i/o

This commit is contained in:
Dmitry Kolesnikov 2016-03-23 22:15:39 +02:00
parent 7794391116
commit c05be3b34e
2 changed files with 126 additions and 41 deletions

View File

@ -125,43 +125,21 @@ handle_call({acc, Key, Val}, _, State0) ->
{Result, State1} = cache_acc(Key, Val, State0),
{reply, Result, State1};
handle_call({add, Key, Val, TTL}, _, State) ->
case cache_has(Key, State) of
true ->
{reply, {error, conflict}, State};
false ->
{reply, ok, cache_put(Key, Val, TTL, State)}
end;
handle_call({add, Key, Val, TTL}, _, State0) ->
{Result, State1} = cache_add(Key, Val, TTL, State0),
{reply, Result, State1};
handle_call({replace, Key, Val, TTL}, _, State) ->
case cache_has(Key, State) of
true ->
{reply, ok, cache_put(Key, Val, TTL, State)};
false ->
{reply, {error, not_found}, State}
end;
handle_call({replace, Key, Val, TTL}, _, State0) ->
{Result, State1} = cache_replace(Key, Val, TTL, State0),
{reply, Result, State1};
handle_call({prepend, Key, Val}, _, State) ->
% @todo: reduce one write
case cache_get(Key, State) of
undefined ->
{reply, ok, cache_put(Key, [Val], undefined, State)};
X when is_list(X) ->
{reply, ok, cache_put(Key, [Val|X], undefined, State)};
X ->
{reply, ok, cache_put(Key, [Val,X], undefined, State)}
end;
handle_call({prepend, Key, Val}, _, State0) ->
{Result, State1} = cache_prepend(Key, Val, State0),
{reply, Result, State1};
handle_call({append, Key, Val}, _, State) ->
% @todo: reduce one write
case cache_get(Key, State) of
undefined ->
{reply, ok, cache_put(Key, [Val], undefined, State)};
X when is_list(X) ->
{reply, ok, cache_put(Key, X++[Val], undefined, State)};
X ->
{reply, ok, cache_put(Key, [X, Val], undefined, State)}
end;
handle_call({append, Key, Val}, _, State0) ->
{Result, State1} = cache_append(Key, Val, State0),
{reply, Result, State1};
handle_call(i, _, State) ->
Heap = cache_heap:refs(State#cache.heap),
@ -185,13 +163,39 @@ handle_call(drop, _, State) ->
handle_call(purge, _, State) ->
{reply, ok, State#cache{heap=cache_heap:purge(State#cache.heap, State#cache.heir)}};
handle_call(_, _, S) ->
{noreply, S}.
handle_call(_, _, State) ->
{noreply, State}.
%%
%%
handle_cast(_, S) ->
{noreply, S}.
handle_cast({put, Key, Val, TTL}, State) ->
{noreply, cache_put(Key, Val, TTL, State)};
handle_cast({remove, Key}, State) ->
{noreply, cache_remove(Key, State)};
handle_cast({acc, Key, Val}, State0) ->
{_, State1} = cache_acc(Key, Val, State0),
{noreply, State1};
handle_cast({add, Key, Val, TTL}, State0) ->
{_, State1} = cache_add(Key, Val, TTL, State0),
{noreply, State1};
handle_cast({replace, Key, Val, TTL}, State0) ->
{_, State1} = cache_replace(Key, Val, TTL, State0),
{noreply, State1};
handle_cast({prepend, Key, Val}, State0) ->
{_, State1} = cache_prepend(Key, Val, State0),
{noreply, State1};
handle_cast({append, Key, Val}, State0) ->
{_, State1} = cache_append(Key, Val, State0),
{noreply, State1};
handle_cast(_, State) ->
{noreply, State}.
%%
%%
@ -356,6 +360,53 @@ tuple_acc(List, X) ->
).
%%
%%
cache_add(Key, Val, TTL, State) ->
case cache_has(Key, State) of
true ->
{{error, conflict}, State};
false ->
{ok, cache_put(Key, Val, TTL, State)}
end.
%%
%%
cache_replace(Key, Val, TTL, State) ->
case cache_has(Key, State) of
true ->
{ok, cache_put(Key, Val, TTL, State)};
false ->
{{error, not_found}, State}
end.
%%
%%
cache_prepend(Key, Val, State) ->
% @todo: reduce one write
case cache_get(Key, State) of
undefined ->
{ok, cache_put(Key, [Val], undefined, State)};
X when is_list(X) ->
{ok, cache_put(Key, [Val|X], undefined, State)};
X ->
{ok, cache_put(Key, [Val,X], undefined, State)}
end.
%%
%%
cache_append(Key, Val, State) ->
% @todo: reduce one write
case cache_get(Key, State) of
undefined ->
{ok, cache_put(Key, [Val], undefined, State)};
X when is_list(X) ->
{ok, cache_put(Key, X++[Val], undefined, State)};
X ->
{ok, cache_put(Key, [X, Val], undefined, State)}
end.
%%
%% remove key from heap segments
heap_remove(Key, Heap) ->

View File

@ -37,10 +37,12 @@
%% cache basic i/o
-export([
put/1,
put_/1,
get/1,
lookup/1,
has/1,
remove/1
remove/1,
remove_/1
]).
%%
@ -51,7 +53,9 @@
add/1,
replace/1,
append/1,
append_/1,
prepend/1,
prepend_/1,
delete/1
]).
@ -73,9 +77,9 @@ groups() ->
{primitives, [parallel],
[lifecycle]},
{basic_io, [parallel],
[put, get, lookup, has, remove]},
[put, put_, get, lookup, has, remove, remove_]},
{extended_io, [parallel],
[acc, set, add, replace, append, prepend, delete]}
[acc, set, add, replace, append, append_, prepend, prepend_, delete]}
].
@ -121,6 +125,13 @@ put(_Config) ->
[{key, val}] = ets:lookup(cache:heap(Cache, 1), key),
ok = cache:drop(Cache).
put_(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:put_(Cache, key, val),
val = cache:get(Cache, key),
ok = cache:drop(Cache).
get(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:put(Cache, key, val),
@ -150,6 +161,13 @@ remove(_Config) ->
false= cache:has(Cache, key),
ok = cache:drop(Cache).
remove_(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:put(Cache, key, val),
true = cache:has(Cache, key),
ok = cache:remove_(Cache, key),
false= cache:has(Cache, key),
ok = cache:drop(Cache).
%%%----------------------------------------------------------------------------
%%%
@ -193,6 +211,14 @@ append(_Config) ->
[a, b, c] = cache:get(Cache, key),
ok = cache:drop(Cache).
append_(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:append_(Cache, key, a),
ok = cache:append_(Cache, key, b),
ok = cache:append_(Cache, key, c),
[a, b, c] = cache:get(Cache, key),
ok = cache:drop(Cache).
prepend(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:prepend(Cache, key, a),
@ -203,6 +229,14 @@ prepend(_Config) ->
[c, b, a] = cache:get(Cache, key),
ok = cache:drop(Cache).
prepend_(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:prepend_(Cache, key, a),
ok = cache:prepend_(Cache, key, b),
ok = cache:prepend_(Cache, key, c),
[c, b, a] = cache:get(Cache, key),
ok = cache:drop(Cache).
delete(_Config) ->
{ok, Cache} = cache:start_link([]),
ok = cache:put(Cache, key, val),