Expand description
Per-account emoji “frecency” (most-used) tracker — SQL-backed.
One row per distinct emoji in emoji_usage (PK (kind,id)); a reuse is an
in-place UPSERT, so the table holds at most one row per emoji and never grows
on repeat use. It’s also pruned to the top MAX_ENTRIES by score.
§The log-space score (why writes and reads are both O(log n))
Each use at time t adds 2^((t - EPOCH)/half_life) points to the emoji’s
score. To rank “right now” you’d multiply every score by the same factor
2^(-(now - EPOCH)/half_life) — but a uniform factor doesn’t change order,
so ranking is just ORDER BY score DESC off an index — no per-row decay math
at read time. Newer uses are worth exponentially more, so old favourites fade
automatically as tastes change.
A soft cap (score = MIN(score + inc, CAP·inc), enforced in the UPSERT) stops
a one-off burst from pinning an emoji forever: a burst saturates at the cap,
and a newer use — worth more per point — overtakes it within a half-life or
two. ranked() converts the stored log-space score back to a normalised
0..CAP “effective” value for the UI.
The row shape (kind, id, url, score, last_used) is also the cross-device sync payload: log-space scores from two devices are directly additive (sum = combined usage). Sync itself is future work.
Structs§
- Emoji
Usage Entry - A ranked usage row handed to the frontend.
scoreis the normalised effective (decayed-to-now) value in0..=SCORE_CAP, not the raw log-space store — so the UI can treat it as a plain 0..25 weight. - Emoji
Use - One use to record (a sent message’s distinct emojis, or a reaction).
Functions§
- bump
- Record one use (reactions; single emoji).
- bump_
batch - Record several uses in one transaction (one sent message → one DB write).
- ranked
- Ranked usage, highest frecency first.
limitcaps the set (None= all).