cx_leaderboard v0.1.0 CxLeaderboard.Indexer View Source
Indexer walks the entire leaderboard and calculates the needed stats, such as rank and percentile.
You can customize the stats by creating a custom indexer — a struct consisting of 2 callback functions:
on_rank
is called when the indexer finishes scanning a set of equal scores, and moves onto a lower scoreon_entry
is called for every entry
It’s important to avoid doing anything on_entry
that can instead be done
on_rank
, since we don’t want to unnecessarily slow down the indexer.
This library comes with a bunch of pre-made on_rank
functions for different
flavor of rank and percentile calculation. See CxLeaderboard.Indexer.Stats
documentation for what’s available.
The on_rank callback
Indexer walks through the sorted dataset of all entries from the highest to
the lowest score. Every time a score is different between entries, it runs the
on_rank
callback for the rank it just finished scanning. The return value of
the function is added to every record in the rank it just walked.
The function receives the following tuple as the argument:
{total_leadeboard_size, chunk_index, chunk_position, chunk_size}
total_leaderboard_size
- total number of entries in the leaderboardchunk_index
- zero-based counter for how many different ranks we have seen so farchunk_position
- zero-based position where this rank started in the leaderboardchunk_size
- how many equal scores are in this rank
Based on these values the function can perform any kind of calculation and return any term as a result.
Let’s see an example of walking through a mini-leaderboard, and see what
numbers get passed into the on_rank
function.
walking score total_size chunk_index chunk_position chunk_size
| 3 n/a n/a n/a n/a
| 3 6 0 0 2
| 2 n/a n/a n/a n/a
| 2 n/a n/a n/a n/a
| 2 6 1 2 3
V 1 6 2 5 1
As the indexer walks the leaderboard, it will only call the on_rank
function
on the rows where score is about to change, therefore some of the rows are
marked n/a.
The on_entry callback
An on_entry
callback is similar to on_rank
but it receives different
parameters, and it’s called on every entry. Its result is added to the entry
for which it’s called.
The function receives the following tuple as the argument:
{entry_index, entry_id, entry_key, rank_stats}
entry_index
- global position in the leaderboard (top is 0)entry_id
- the id used for fetching recordsentry_key
- either{score, id}
or{score, tiebreaker, id}
depending on what was insertedrank_stats
- the return value of theon_rank
function
Due to rank_stats
parameter it’s possible to make more granular calculations
based on whatever was provided by the on_rank
function.
Link to this section Summary
Functions
Same as index/3
but counts the elements for you so that there is no need to
supply that number. This is inefficient if you already know the total count
Build leaderboard index from an enumerable containing Entry.key()
-type
elements. Supply the total count for efficiency
Create a custom indexer by supplying 2 functions: on_rank
and on_entry
.
See CxLeaderboard.Indexer.Stats
for available functions, or implement custom
ones
Link to this section Types
on_entry() :: ({non_neg_integer(), term(), CxLeaderboard.Entry.key(), term()} -> term())
on_rank() :: ({non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()} -> term())
t() :: %CxLeaderboard.Indexer{ on_entry: Indexer.on_entry(), on_rank: Indexer.on_rank() }
Link to this section Functions
Same as index/3
but counts the elements for you so that there is no need to
supply that number. This is inefficient if you already know the total count.
Build leaderboard index from an enumerable containing Entry.key()
-type
elements. Supply the total count for efficiency.
Create a custom indexer by supplying 2 functions: on_rank
and on_entry
.
See CxLeaderboard.Indexer.Stats
for available functions, or implement custom
ones.