Step 1 of 3 · Reading · ~2 min
Redis Lists
Lists
Lists: your first non-scalar type
Every value you've stored so far has been a single string. Redis's list type is where your server starts needing real data structures — an ordered sequence of strings living behind one key, with fast insertion at both ends.
Choosing the underlying structure
A Python list looks tempting, but list.insert(0, x) is O(n) — every push to the front shifts the whole array. Real Redis uses a doubly-linked list (historically) or a quicklist of linked ziplists. In your server, the simplest correct choice is collections.deque, which gives O(1) appendleft and append:
The head/tail ordering subtlety
LPUSH mylist a b c doesn't push a, then b, then c onto the head one at a time and leave you with a b c — each push happens in argument order, so the last argument ends up closest to the head:
LPUSH mylist a b c
# step 1: pushLeft(a) -> [a]
# step 2: pushLeft(b) -> [b, a]
# step 3: pushLeft(c) -> [c, b, a]
Final list: c, b, a. This trips people up constantly — write a small trace like the one above before you code it, and test it explicitly.
RPUSH is the mirror image: append each value in order to the tail, so RPUSH mylist a b c yields a, b, c in that natural order.
Type checking and shared storage
Because a Redis key can hold exactly one type at a time, before pushing you must check whether the key already exists as something other than a list (e.g. a string set with SET). If your server keeps separate dicts per type (strings, lists, hashes, ...), checking "does this key exist in a different dict" is enough:
If the check fails, reply with the exact wire error:
-WRONGTYPE Operation against a key holding the wrong kind of value\r\n
Note the error starts with - (RESP error prefix) and is terminated with \r\n — not \n. Getting the line ending wrong is a classic bug that only shows up when a strict client parses your reply.
The reply: an integer
Both LPUSH and RPUSH reply with the new length of the list after the push, encoded as a RESP integer: :3\r\n. This lets clients chain pushes and know the resulting size without a separate LLEN call — keep that return value in mind as you wire up your command dispatcher.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…