R4.05.2 · dive 2
Top-N and around-me
Two reads serve every leaderboard view. The top-N is the first N positions of the order; the around-me window is a slice of positions either side of a player's own. Both read the same order and leave it unchanged.
A leaderboard view is one of two shapes. The first is the top-N — the leader and the players right behind. The second is around-me — where a single player stands, with a few competitors above and below. Both are reads of the same sorted order: the top-N reads from the head, and around-me first locates a player's rank, then reads the band centred on it. Pick a view on the right and watch the index range each read walks.
Two views, one order · the top-N head vs the around-me band
Top-N — a read from the head
The top-N is the first N positions of the board read high-to-low. ZREVRANGE reads a
rank range from the top, and WITHSCORES returns each member's score alongside it:
ZREVRANGE leaderboard 0 9 WITHSCORES # the top 10
The arguments 0 9 are rank indices, inclusive — positions 0 through 9, the
leader through the tenth player. To read the top 5, the range is 0 4; for the top 20,
0 19. The read walks N members from the head, which is
O(log N + N): the log to find the head, then N to read across. The board is unchanged
— ZREVRANGE reads the order, never writes it. Redis 6.2 folded the range commands
into a unified ZRANGE … REV, which reads the identical top-N; only the spelling
differs.
The top-N is a head-read of the order: ZREVRANGE 0 N-1 WITHSCORES returns
the first N positions and their scores, and reads but never writes the set.
Pagination — the top-N, page by page
A large board is read a page at a time, each page a rank range further down the order:
ZREVRANGE leaderboard 0 19 WITHSCORES # page 1: ranks 1–20 ZREVRANGE leaderboard 20 39 WITHSCORES # page 2: ranks 21–40
Page p of size s is the range (p−1)·s through
p·s − 1. ZCARD returns the member count, which
divided by the page size gives the page count. Each page is the same head-read, offset down the order.
Pages of three · each page a rank range offset down the order
A page is the top-N offset down the order — page p is the rank range
(p−1)·s to p·s−1 — and
ZCARD over the page size gives the count.
Around-me — locate, then read the band
The around-me view shows a player their standing against nearby competitors. It is two reads. First locate the
player's rank with ZREVRANK; then read the rank band centred on it:
ZREVRANK leaderboard "player:alice" # say it returns 50 ZREVRANGE leaderboard 45 55 WITHSCORES # ranks 45–55: alice with five either side
With a window half-width k, the band is rank − k through
rank + k. Near the top the band clamps at 0 — a player at rank 2 with k = 5 reads
0 7, since there is nothing above rank 0. The band is a slice of the existing order;
neither read changes the set. Locate, then read the band around the located rank.
Around-me is locate-then-read: ZREVRANK finds the rank, then a rank-range
read takes the band rank−k to rank+k, clamped at the top
edge.
In Portal — ranking the progress percent
The pattern is two reads over a sorted order. Portal runs no sorted set. It records a learner's lesson
progress as a percent — Portal.Enrollment.Progress, the field
percent :: 0..100, namespace PRG, an in-memory store row.
There is no progress ranking; the percent is a stored value.
# Portal.Enrollment.Progress — the real struct (echo/apps/portal): percent 0..100, namespace PRG %Portal.Enrollment.Progress{enrollment_id: "ENR…", lesson_id: "LSN…", percent: 72} # the two reads a ranked view would add over that percent (the applied pattern — Portal runs no sorted set) ZREVRANGE board 0 9 WITHSCORES # the ten learners furthest along ZREVRANK board "learner:dana" # then a rank-range read around dana's place
A ranked view of learners by progress is this dive applied to that data. Score each learner by their percent
with ZADD board <percent> <learner>, and the two reads serve the two views:
ZREVRANGE board 0 9 WITHSCORES reads the ten learners furthest along, and
ZREVRANK then a rank-range read shows one learner where they stand among their
nearest peers. State it plainly: the percent is in Portal's store today; the top-N and around-me reads are the
standard way to present a ranked view of it, and both read the percent order without changing it.
The top-N is a head-read of the score order (ZREVRANGE 0 N-1) and around-me is a
band centred on a rank (ZREVRANK, then a rank-range read).
Portal stores each learner's progress as a percent (the PRG
struct, an in-memory store row). A ranked view scores by that percent and reads the top learners as a
head-read and a single learner's neighbourhood as a band around their rank — Portal runs no sorted set;
the reads are the structure to add over the percent it records.
Two reads cover every view: the head for the top-N, a band for around-me. Both read the order — Portal's progress percent, ranked — and leave it untouched.
emq:{queue}:prioritized); the
settled EchoMQ 2.0 design (the protocol break on the first EMQ rung, emq.1) renames
it to emq:{queue}:prioritized — emq: replacing emq:, every Lua key
declared in KEYS[], meta.version at echomq:2.0.0 — with the read
semantics unchanged. A range read over a sorted set is a property of the score order, independent of the prefix
or the version.
References
The range read that returns the top-N from the head, the rank lookup that anchors an around-me window, and the sorted set both reads walk.
Sources
- Redis — ZREVRANGE — read a rank range from the top, the top-N and the pagination read.
- Redis — ZREVRANK — locate a member's rank, the first read of an around-me window.
- Redis — Sorted sets — the ordered structure both reads walk.
Related in this course
- R4.05 · Leaderboards — the module hub.
- R4.05.1 · ZADD and ZREVRANK — the previous dive: the score in, the rank out.
- R4.05.3 · The score-update path — the next dive: updating a score, the rank recomputed.
- R4 · Time, Delay & Priority — the chapter.
- R4 · Score as meaning — the score is the semantic axis.
- E4 · Groups — the dedicated EchoMQ course: the group reads on the same order.