Permalink
Browse files

tags

  • Loading branch information...
1 parent 2256e12 commit 11f5ea3fc340d4d96772c54ac0a51f44f2f909c1 spin committed Feb 15, 2011
Showing with 75 additions and 29 deletions.
  1. +33 −15 src/reducks.erl
  2. +0 −12 test/basic_test.erl
  3. +2 −2 test/flow_test.erl
  4. +40 −0 test/tags_test.erl
View
48 src/reducks.erl
@@ -1,7 +1,7 @@
%%% @version 0.1
-module(reducks).
--export([snap/3, snap/4, purge/2]).
+-export([snap/3, snap/4, mark/3, purge/2, marked/2]).
snap(Client, Key, {Field, Value}, {Make}) ->
snap(Client, Key, {Field, Value}, {Make, 120000});
@@ -20,7 +20,7 @@ snap(Client, Key, {Make, Timeout}) ->
case catch erldis:hgetall(Client, Key) of
[] ->
%% No data here - try lock
- KeyLock = get_lock_key(Key),
+ KeyLock = <<Key/binary, ":lock">>,
TS = get_timestamp(0),
case catch erldis:setnx(Client, KeyLock, n_to_b(TS+Timeout)) of
true ->
@@ -56,7 +56,7 @@ snap(Client, Key, {Make, Timeout}) ->
end
end;
{'EXIT', _} ->
- %% Rare bug workaround
+ %% Rare "unsubscribe" bug workaround
erldis:unsubscribe(Client),
snap(Client, Key, {Make, Timeout})
end;
@@ -69,42 +69,60 @@ snap(Client, Key, {Make, Timeout}) ->
{ok, Data}
end.
-%% @doc Purge keys
-purge(Client, Keys) ->
- erldis:delkeys(Client, Keys).
-
-%%
-%% Private
-%%
-
+%% @private
set_data(Client, Key, Make, Timeout, KeyLock) ->
{{data, Data}, {ttl, TTL}} = Make(),
+
+ erldis:set_pipelining(Client, true),
erldis:hmset(Client, Key, Data),
if TTL =/= infinity ->
%% Set expiration if needed
erldis:expire(Client, Key, TTL)
end,
erldis:publish(Client, KeyLock, <<"ok">>),
erldis:del(Client, KeyLock),
+ erldis:get_all_results(Client),
+ erldis:set_pipelining(Client, false),
snap(Client, Key, {Make, Timeout}).
%% Convert integer to binary
+%% @private
n_to_b(N) ->
list_to_binary(integer_to_list(N)).
+%% @private
b_to_n(nil) ->
0;
+%% @private
b_to_n(B) ->
list_to_integer(binary_to_list(B)).
+%% @private
get_timestamp(Diff) ->
{Mega, Secs, Msecs} = now(),
((Mega*1000000 + Secs)*1000000 + Msecs) div 1000 + Diff.
-%% @spec get_loget_lock_key(Key::string()) -> string()
-%% @doc Get lock key
-get_lock_key(Key) ->
- <<Key/binary, ":lock">>.
+
+%% @doc Mark keys with tags.
+mark(Client, Keys, Tags)->
+ erldis:set_pipelining(Client, true),
+ [ erldis:sadd(Client, <<"tag:", Tag/binary>>, Key) ||
+ Key <- Keys, Tag <- Tags ],
+ erldis:get_all_results(Client),
+ erldis:set_pipelining(Client, false).
+
+%% @doc Get keys by tags.
+marked(Client, Tags) ->
+ erldis:sunion(Client, make_tags(Tags)).
+
+%% @doc Purge keys
+purge(Client, Tags) ->
+ Keys = marked(Client, Tags),
+ erldis:delkeys(Client, lists:flatten([make_tags(Tags), Keys])).
+
+%% @private
+make_tags(Tags)->
+ [ <<"tag:", Tag/binary>> || Tag <-Tags ].
%%
%% Tests
View
12 test/basic_test.erl
@@ -1,12 +0,0 @@
--module(basic_test).
-
--ifdef(TEST).
--compile(export_all).
--include_lib("eunit/include/eunit.hrl").
-
-
-key_test_() -> fun() ->
- ?assertEqual(<<"key:lock">>, reducks:get_lock_key(<<"key">>))
- end.
-
--endif.
View
4 test/flow_test.erl
@@ -18,7 +18,7 @@ persistence_test_() ->
?assertNot({ok, [Data1]} == reducks:snap(Client, Key, {Make1})),
?assertEqual({ok, [Data]}, reducks:snap(Client, Key, {Make1})),
- reducks:purge(Client, [Key]),
+ erldis:delkeys(Client, [Key]),
?assertEqual({ok, [Data1]}, reducks:snap(Client, Key, {Make1})),
erldis:quit(Client)
end
@@ -35,7 +35,7 @@ equal_test_()->
?assertEqual({ok, [Data]},
reducks:snap(Client, Key, Data, {Make})),
?assertEqual({ok, [Data]},
- reducks:snap(Client, Key, Data1, {Make})),
+ reducks:snap(Client, Key, Data1, {Make1})),
?assertEqual({ok, equal},
reducks:snap(Client, Key, Data, {Make})),
erldis:quit(Client)
View
40 test/tags_test.erl
@@ -0,0 +1,40 @@
+-module(tags_test).
+
+-ifdef(TEST).
+-compile(export_all).
+-include_lib("eunit/include/eunit.hrl").
+
+tag_test_()->
+ {"Tags",
+ setup, fun test_util:flushall/0,
+ fun(_) -> test_util:flushall() end,
+ fun()->
+ Tag1 = <<"one">>,
+ Tag2 = <<"two">>,
+ Keys1 = [<<"key1-one">>, <<"key1-two">>],
+ Keys2 = [<<"key2-one">>, <<"key2-two">>],
+ {ok, Client} = erldis:connect(),
+ ?assertEqual(ok, reducks:mark(Client, Keys1, [Tag1])),
+ ?assertEqual(ok, reducks:mark(Client, Keys2, [Tag1, Tag2])),
+ ?assertEqual([], lists:subtract(
+ lists:flatten(Keys1, Keys2),
+ reducks:marked(Client, [Tag1, Tag2]))),
+ ?assertEqual([], lists:subtract(
+ lists:flatten(Keys1, Keys2),
+ reducks:marked(Client, [Tag1]))),
+ ?assertEqual([], lists:subtract(Keys2,
+ reducks:marked(Client, [Tag2]))),
+ ?assertEqual([], reducks:marked(Client, [<<"noexist">>])),
+
+ reducks:purge(Client, [Tag1, Tag2]),
+ ?assertEqual([], reducks:marked(Client, [Tag1, Tag2])),
+
+ erldis:quit(Client)
+ end
+ }.
+
+
+
+
+
+-endif.

0 comments on commit 11f5ea3

Please sign in to comment.