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 score

  • on_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 leaderboard
  • chunk_index - zero-based counter for how many different ranks we have seen so far
  • chunk_position - zero-based position where this rank started in the leaderboard
  • chunk_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 records
  • entry_key - either {score, id} or {score, tiebreaker, id} depending on what was inserted
  • rank_stats - the return value of the on_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

Link to this type t() View Source
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.

Link to this function index(keys, cnt, indexer \\ %__MODULE__{}) View Source

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.