Skip to content

Commit

Permalink
Add and test redis-2.2 commands ({get,set}{range,bit}, brpoplpush)
Browse files Browse the repository at this point in the history
Implements:
  - getbit
  - setbit
  - getrange
  - setrange
  - brpoplpush

Tests added for all except brpoplpush.

All 171 tests pass.
  • Loading branch information
mattsta committed Dec 15, 2010
1 parent 688a612 commit 76c5fff
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 12 deletions.
11 changes: 10 additions & 1 deletion include/redis-cmds.lfe
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,12 @@
(redis-cmd-i append (_key_ _value_))

; return a substring out of a larger string
(redis-cmd-b substr (_key_ _start_ _end_))
(redis-cmd-b substr (_key_ _start_ _end_)) ; substr = getrange in 2.2+
(redis-cmd-b getrange (_key_ _start_ _end_)) ; getrange = substr for redis 2.2+
(redis-cmd-i setrange (_key_ _start_ _end_))

(redis-cmd-i getbit (_key_ _position_))
(redis-cmd-i-tf setbit (_key_ _position_ _value_))

; return the length of a string
(redis-cmd-i strlen (_key_))
Expand Down Expand Up @@ -165,6 +170,10 @@
; Return and remove (atomically) the last element of the source List stored at _srckey_ and push the same element to the destination List stored at _dstkey_
(redis-cmd-b rpoplpush (_srckey_ _dstkey_))

; Blocking rpoplpush
(redis-cmd-b brpoplpush (_srckey_ _dstkey_))



;; Commands operating on sets ;;

Expand Down
5 changes: 3 additions & 2 deletions src/er.app.src
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{application, er,
[
{description, "Erlang Redis Library Application"},
{vsn, "0.5.0"},
{description, "Erlang Redis Library"},
% version numbers are: {redis.version}-er-{er.version}
{vsn, "2.2-er-1.0"},
{modules, []},
{registered, [er_sup]},
{applications, [
Expand Down
1 change: 1 addition & 0 deletions src/er_pool.erl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ handle_call({cmd, Parts}, From,
handle_call({cmd, Parts}, From,
#state{available = [H|T], reserved = R} = State) when
hd(Parts) =:= <<"blpop">> orelse
hd(Parts) =:= <<"brpoplpush">> orelse
hd(Parts) =:= <<"brpop">> ->
Caller = self(),
spawn(fun() ->
Expand Down
2 changes: 1 addition & 1 deletion src/er_redis.erl
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ read_body(Socket, Size) ->
read_multi_bulk(_Data, 0, Acc) ->
lists:reverse(Acc);
read_multi_bulk(_Data, -1, _Acc) ->
{ok, nil}; % Occurs during b[lr]pop
{ok, nil}; % Occurs during b[lr]pop. Maybe during brpoplpush too
read_multi_bulk(Socket, Count, Acc) when Count > 0 ->
Acc1 = [read_resp(Socket) | Acc],
read_multi_bulk(Socket, Count-1, Acc1).
Expand Down
71 changes: 63 additions & 8 deletions test/er_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,80 @@ er_basic_commands_test_() ->
?_E(2, er:dbsize(C)),
?_E(ok, er:set(C, expireme, expiremecontent)),
?_E(true, er:expire(C, expireme, 30)),
?_E(false, er:expire(C, expireme, 30)),
?_E(true, er:expire(C, expireme, 30)), % behavior changed in redis 2.2
?_E(false, er:expire(C, expireme_noexist, 30)),
?_assertMatch(TTL when TTL =:= 29 orelse TTL =:= 30,
er:ttl(C, expireme)),
?_E(true, er:setnx(C, abc123, abc)),
?_E(false, er:setnx(C, abc123, abc)),
?_E(false, er:msetnx(C, [abc123, abc, abc234, def])),
?_E(true, er:msetnx(C, [abc234, def, abc567, hij]))
?_E(false, er:setnx(C, abc123, abc)),
?_E(false, er:msetnx(C, [abc123, abc, abc234, def])),
?_E(true, er:msetnx(C, [abc234, def, abc567, hij])),
% getset,
% mget,
% setex,
% ttl,
% ttl,
% mset,
% incr,
% incrby,
% decr,
% decrby,
% append,
% substr,

% bitkey: 01000000 = @
?_E(true, er:setbit(C, bitkey, 1, 1)),
?_E(<<"@">>, er:get(C, bitkey)),
?_E(1, er:getbit(C, bitkey, 1)),
?_E(0, er:getbit(C, bitkey, 0)),
?_E(0, er:getbit(C, bitkey, 12)),
?_E(0, er:getbit(C, bitkey, 32)),
?_E(0, er:getbit(C, bitkey, 64)),
?_E(0, er:getbit(C, bitkey, 999)),
% test setting arbitrarily large index
?_E(true, er:setbit(C, bitkey, 1024968, 1)),
?_E(0, er:getbit(C, bitkey, 1024967)),
?_E(1, er:getbit(C, bitkey, 1024968)),
?_E(0, er:getbit(C, bitkey, 1024969)),
% binarykey
?_E(true, er:setbit(C, binarykey, 0, 1)),
% 10000000 = 128
?_E(<<128>>, er:get(C, binarykey)),
?_E(true, er:setbit(C, binarykey, 7, 1)),
% 10000001 = 128
?_E(<<129>>, er:get(C, binarykey)),
?_E(true, er:setbit(C, binarykey, 64, 1)),
% binarykey = (see next three lines)
% [10000001]
% [00000000][00000000][00000000][00000000][00000000][00000000][00000000]
% [1000000]
% = 129, 8x0, 8x0, 8x0, 8x0, 8x0, 8x0, 8x0, 128
?_E(<<129,0,0,0,0,0,0,0,128>>, er:get(C, binarykey)),
% binaryint
% 5 = 00000101
% *NB:* Binary 5 is not the same as ASCII 5.
?_E(ok,er:set(C, binaryint, <<5>>)),
?_E(0, er:getbit(C, binaryint, 0)),
?_E(0, er:getbit(C, binaryint, 1)),
?_E(0, er:getbit(C, binaryint, 2)),
?_E(0, er:getbit(C, binaryint, 3)),
?_E(0, er:getbit(C, binaryint, 4)),
?_E(1, er:getbit(C, binaryint, 5)),
?_E(0, er:getbit(C, binaryint, 6)),
?_E(1, er:getbit(C, binaryint, 7)),
% nothinghere. substr got renamed getrange in redis 2.2
% getrange is now just an alias to substr in redis
?_E(nil, er:getrange(C, nothinghere, 1, 3)),
?_E(nil, er:substr(C, nothinghere, 1, 3)),
% rangekey tests
?_E(ok, er:set(C, rangekey, "Hello")),
?_E(<<"ell">>, er:getrange(C, rangekey, 1, 3)),
?_E(<<"ell">>, er:substr(C, rangekey, 1, 3)),
?_E(5, er:setrange(C, rangekey, 1, "no")),
?_E(<<"nolo">>, er:getrange(C, rangekey, 1, 4)),
% zero padding happens when adding to a nonexistent key
?_E(13, er:setrange(C, rangeemptykey, 3, "Empty Test")),
?_E(<<0,0,0,"Empty Test">>, er:get(C, rangeemptykey)),
% reading past the length of a string
?_E(nil, er:getrange(C, rangekey, 64, 32)),
?_E(nil, er:substr(C, rangekey, 64, 32))
]
end
}.
Expand Down Expand Up @@ -103,6 +157,7 @@ er_lists_commands_test_() ->
% blpop
% brpop
% rpoplpush
% brpoplpush
]
end
}.
Expand Down Expand Up @@ -134,7 +189,7 @@ er_sets_commands_test_() ->
?_E(1, er:scard(C, setA)),
?_E(2, er:scard(C, setB)),
?_E(true, er:sismember(C, setB, bmember2)),
?_E(false, er:sismember(C, setB, bmember9))
?_E(false, er:sismember(C, setB, bmember9))
% sinter
% sinterstore
% sunion
Expand Down

0 comments on commit 76c5fff

Please sign in to comment.