{"id":18151427,"url":"https://github.com/jur0/leaderboard","last_synced_at":"2025-04-28T18:09:17.428Z","repository":{"id":57515495,"uuid":"82097937","full_name":"jur0/leaderboard","owner":"jur0","description":"Leaderboard (rank table) based on ETS","archived":false,"fork":false,"pushed_at":"2017-04-17T11:41:24.000Z","size":21,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-28T18:09:08.288Z","etag":null,"topics":["elixir","ets","leaderboard","ranking","scoreboard"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jur0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-15T19:27:36.000Z","updated_at":"2025-02-10T04:43:25.000Z","dependencies_parsed_at":"2022-08-30T04:20:45.846Z","dependency_job_id":null,"html_url":"https://github.com/jur0/leaderboard","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jur0%2Fleaderboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jur0%2Fleaderboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jur0%2Fleaderboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jur0%2Fleaderboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jur0","download_url":"https://codeload.github.com/jur0/leaderboard/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251362153,"owners_count":21577403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","ets","leaderboard","ranking","scoreboard"],"created_at":"2024-11-02T01:07:38.093Z","updated_at":"2025-04-28T18:09:17.408Z","avatar_url":"https://github.com/jur0.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Leaderboard\n\n[![Travis](https://travis-ci.org/jur0/leaderboard.svg?branch=master)](https://travis-ci.org/jur0/leaderboard)\n[![Hex.pm](https://img.shields.io/hexpm/v/leaderboard.svg)](https://hex.pm/packages/leaderboard)\n\nLeaderboard (rank table) implementation using ETS tables.\n\n## Installation\n\nIf [available in Hex](https://hex.pm/docs/publish), the package can be installed\nby adding `leaderboard` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [{:leaderboard, \"~\u003e 0.2\"}]\nend\n```\n\n## Usage\n\nFirst off, the leaderboard `GenServer` process must be started. Typically, it's\nstarted as a part of the supervision tree:\n\n  ```elixir\n  worker(Leaderboard, [Leaderboard.Test])\n  ```\n\nIt requires `table_name` argument which is the name of the leaderboard. It\nmust be an atom. The leaderboard tables shouldn't be started dynamically\nas the leaderboard names are atoms and they shouldn't be generated\ndynamically.\n\nThe leaderboard's API has functions for inserting, updating and deleting\nrecords. These are write functions and are serialised. Also, there are functions\nfor reading records in specific order and/or with limited number of returned\nvalues:\n\n  ```elixir\n  Leaderboard.insert(Leaderboard.Test, 30, \"foo\")\n  Leaderboard.insert(Leaderboard.Test, 5, \"bar\")\n  Leaderboard.insert(Leaderboard.Test, 19, \"baz\")\n\n  # update \"bar\" to 10\n  Leaderboard.insert(Leaderboard.Test, 10, \"bar\")\n\n  # lookup the score of \"bar\"\n  Leaderboard.lookup(Leaderboard.Test, \"bar\")\n  #=\u003e 10\n\n  # select top 2 records in ascending order\n  Leaderboard.select(Leaderboard.Test, :ascend, 2)\n  #=\u003e [{10, \"bar\"}, {19, \"baz\"}]\n\n  # match all records that have score \u003e 10 in descending order and return\n  # their keys\n  match_spec = [{{{:\"$1\",:\"$2\"}}, [{:\"\u003e\", :\"$1\", 10}], [:\"$2\"]}]\n  Leaderboard.match(Leaderboard.Test, match_spec, :descend)\n  #=\u003e [\"foo\", \"baz\"]\n\n  # delete \"foo\" record\n  Leaderboard.delete(Leaderboard.Test, \"foo\")\n  ```\n\n## Implementation\n\nThe leaderboard is composed of a `GenServer` process and two ETS tables. The\nETS `key_table` is of type `:set`:\n\n| key   | value   |\n| ----- | ------- |\n| `key` | `score` |\n\nThe second ETS table called `score_table` is of type `:ordered_set`.\nIt stores only keys without any values:\n\n| key            | value |\n| -------------- | :---: |\n| `{score, key}` | -     |\n\nWhen a new record is inserted into the leaderboard, the record is inserted\ninto both tables. All the writes are serialised via the `GenServer` process.\n\nThe ETS tables are `:protected`, so only the `GenServer` process that owns\nthem can write. All the other processes are allowed just to read. Read\noperations are not serialised so they can be done in concurrent manner.\n\n## Benchmarks\n\nThe `score_table` is `:ordered_set`. With the size of the table also\nincreases the time needed for insert operation:\n\n```\n## LeaderboardBench\nbenchmark name                   iterations   average time\nInsert to table of size 1000         200000   8.42 µs/op\nInsert to table of size 10000        200000   9.37 µs/op\nInsert to table of size 100000       200000   10.06 µs/op\nInsert to table of size 1000000      100000   10.55 µs/op\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjur0%2Fleaderboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjur0%2Fleaderboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjur0%2Fleaderboard/lists"}