Redis/INCR

When you INCR a nonexistent key in Redis, it is initialized to zero and then incremented. By contrast, attempting to INCR a nonexistent key in memcached (version 1.2.6 or later) will result in failure. This article describes an implementation of INCR on top of Redis that behaves in a fashion consistent with the memcached protocol, using pipelines.

The idea is to map INCR to this pipeline:

RPUSH key (some value)
INCR key 
RPOP (some value) 

The value to return to the user is the second of the three returned by MULTI.

Scenario 1: Nonexistent key

edit
redis> MULTI
OK
redis> RPUSH mykey 1
QUEUED
redis> INCR mykey
QUEUED
redis> RPOP mykey
QUEUED
redis> EXEC
1) (integer) 1
2) (error) ERR Operation against a key holding the wrong kind of value
3) "1"

Outcome: error. Key is still absent because RPOPing the last element out of a list nullifies it.

Scenario 2: Key is an integer

edit
redis> SET mykey 1
OK
redis> MULTI
OK
redis> RPUSH mykey 1
QUEUED
redis> INCR mykey
QUEUED
redis> RPOP mykey
QUEUED
redis> EXEC
1) (error) ERR Operation against a key holding the wrong kind of value
2) (integer) 2
3) (error) ERR Operation against a key holding the wrong kind of value

Outcome: key incremented.

Scenario 3: Key is a list

edit
redis> del mykey
(integer) 1
redis> RPUSH mykey 1
(integer) 1
redis> RPUSH mykey 2
(integer) 2
redis> RPUSH mykey 3
(integer) 3
redis> LRANGE mykey 0 inf
1) "1"
redis> LRANGE mykey 0 -1
1) "1"
2) "2"
3) "3"
redis> MULTI
OK
redis> RPUSH mykey 1
QUEUED
redis> INCR mykey
QUEUED
redis> RPOP mykey
QUEUED
redis> EXEC
1) (integer) 4
2) (error) ERR Operation against a key holding the wrong kind of value
3) "1"
redis> LRANGE mykey 0 -1
1) "1"
2) "2"
3) "3"

Outcome: error. Key is unmodified, because RPUSH and RPOP are each other’s inverse.

Scenario 4: Key is some other type

edit
redis> HMSET mykey year 2012
OK
redis> MULTI
OK
redis> RPUSH mykey 1
QUEUED
redis> INCR mykey
QUEUED
redis> RPOP mykey
QUEUED
redis> EXEC
1) (error) ERR Operation against a key holding the wrong kind of value
2) (error) ERR Operation against a key holding the wrong kind of value
3) (error) ERR Operation against a key holding the wrong kind of value

Outcome: error.