Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions kernelboard/api/leaderboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def _get_query():
SELECT r.*
FROM scoped_submissions s
JOIN LATERAL (
SELECT submission_id, runner, score, secret, passed
SELECT id, submission_id, runner, score, secret, passed
FROM leaderboard.runs
WHERE submission_id = s.id
OFFSET 0
Expand Down Expand Up @@ -284,7 +284,10 @@ def _get_query():
s.file_name AS file_name,
r.submission_id AS submission_id,
COALESCE(sc.submission_count, 0) AS submission_count,
RANK() OVER (PARTITION BY r.runner, u.id ORDER BY r.score ASC) AS rank
ROW_NUMBER() OVER (
PARTITION BY r.runner, s.user_id
ORDER BY r.score ASC, s.submission_time ASC, s.id ASC, r.id ASC
) AS rank
FROM scoped_runs r
JOIN scoped_submissions s ON r.submission_id = s.id
LEFT JOIN leaderboard.user_info u ON s.user_id = u.id
Expand Down
10 changes: 5 additions & 5 deletions kernelboard/api/leaderboard_summaries.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
leaderboard_summaries_bp = Blueprint("leaderboard_summaries_bp", __name__, url_prefix="/leaderboard-summaries")

# Redis cache key prefix for ended leaderboard top_users
CACHE_KEY_PREFIX = "lb_top_users:v2:"
CACHE_KEY_PREFIX = "lb_top_users:v3:"


# =============================================================================
Expand Down Expand Up @@ -354,9 +354,9 @@ def _get_query_for_ids():
s.user_id,
u.user_name,
r.score,
RANK() OVER (
ROW_NUMBER() OVER (
PARTITION BY s.leaderboard_id, r.runner, s.user_id
ORDER BY r.score ASC
ORDER BY r.score ASC, s.submission_time ASC, s.id ASC, r.id ASC
) AS personal_submission_rank
FROM leaderboard.runs r
JOIN leaderboard.submission s ON r.submission_id = s.id
Expand Down Expand Up @@ -475,9 +475,9 @@ def _get_query():
s.user_id,
u.user_name,
r.score,
RANK() OVER (
ROW_NUMBER() OVER (
PARTITION BY s.leaderboard_id, r.runner, s.user_id
ORDER BY r.score ASC
ORDER BY r.score ASC, s.submission_time ASC, s.id ASC, r.id ASC
) AS personal_submission_rank
FROM leaderboard.runs r
JOIN leaderboard.submission s ON r.submission_id = s.id
Expand Down
4 changes: 2 additions & 2 deletions kernelboard/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ def index():
s.leaderboard_id AS leaderboard_id,
u.user_name AS user_name,
r.score AS score,
RANK() OVER (PARTITION BY s.leaderboard_id, r.runner, u.id
ORDER BY r.score ASC) AS personal_submission_rank
ROW_NUMBER() OVER (PARTITION BY s.leaderboard_id, r.runner, s.user_id
ORDER BY r.score ASC, s.submission_time ASC, s.id ASC, r.id ASC) AS personal_submission_rank
FROM leaderboard.runs r
JOIN leaderboard.submission s ON r.submission_id = s.id
JOIN active_leaderboards a ON s.leaderboard_id = a.id
Expand Down
5 changes: 4 additions & 1 deletion kernelboard/leaderboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ def leaderboard(leaderboard_id: int):
r.score AS score,
s.submission_time AS submission_time,
s.file_name AS file_name,
RANK() OVER (PARTITION BY r.runner, u.id ORDER BY r.score ASC) AS rank
ROW_NUMBER() OVER (
PARTITION BY r.runner, s.user_id
ORDER BY r.score ASC, s.submission_time ASC, s.id ASC, r.id ASC
) AS rank
FROM leaderboard.runs r
JOIN leaderboard.submission s ON r.submission_id = s.id
LEFT JOIN leaderboard.user_info u ON s.user_id = u.id
Expand Down
4 changes: 2 additions & 2 deletions ranking_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ def ensure_snapshot_table(conn):
s.user_id,
u.user_name,
r.score,
RANK() OVER (
ROW_NUMBER() OVER (
PARTITION BY s.leaderboard_id, r.runner, s.user_id
ORDER BY r.score ASC
ORDER BY r.score ASC, s.submission_time ASC, s.id ASC, r.id ASC
) AS personal_submission_rank
FROM leaderboard.runs r
JOIN leaderboard.submission s ON r.submission_id = s.id
Expand Down
51 changes: 49 additions & 2 deletions tests/api/test_leaderboard_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ def test_hacked_submissions_are_hidden_from_public_leaderboard(client, app):
assert "visible_clean_status.py" in ranked_files


def test_equal_best_runs_preserve_ties_and_distinct_submission_count(client, app):
def test_equal_best_runs_keep_one_entry_and_distinct_submission_count(client, app):
before = client.get("/api/leaderboard/339").get_json()["data"]["rankings"]
gpu, entries = next(iter(before.items()))
winner = entries[0]
Expand All @@ -455,6 +455,53 @@ def test_equal_best_runs_preserve_ties_and_distinct_submission_count(client, app
conn.commit()
after = client.get("/api/leaderboard/339").get_json()["data"]["rankings"][gpu]
tied = [item for item in after if item["submission_id"] == winner["submission_id"]]
assert len(tied) == 2
assert len(tied) == 1
assert all(item["score"] == winner["score"] for item in tied)
assert all(item["submission_count"] == winner["submission_count"] for item in tied)


def test_tied_submissions_keep_earliest_per_account_and_preserve_other_users(client, app):
before = client.get("/api/leaderboard/339").get_json()["data"]["rankings"]
gpu, entries = next(iter(before.items()))
winner = entries[0]
with app.app_context():
conn = get_db_connection()
with conn.cursor() as cur:
cur.execute(
"INSERT INTO leaderboard.user_info (id, user_name) VALUES (%s, %s)",
("tie-regression-user", winner["user_name"]),
)
for submission_id, new_user in [(990101, False), (990102, False), (990103, True)]:
cur.execute(
"""
INSERT INTO leaderboard.submission (
id, leaderboard_id, file_name, user_id, code_id, submission_time, done, status
)
SELECT %s, leaderboard_id, 'tie_regression.py',
CASE WHEN %s THEN 'tie-regression-user' ELSE user_id END,
code_id, submission_time - INTERVAL '1 day', done, status
FROM leaderboard.submission WHERE id = %s
""",
(submission_id, new_user, winner["submission_id"]),
)
cur.execute(
"""
INSERT INTO leaderboard.runs (
id, submission_id, start_time, end_time, mode, secret,
runner, score, passed, compilation, meta, result, system_info
)
SELECT %s + ROW_NUMBER() OVER (), %s, start_time, end_time, mode, secret,
runner, score, passed, compilation, meta, result, system_info
FROM leaderboard.runs
WHERE submission_id = %s AND runner = %s
""",
(submission_id * 100, submission_id, winner["submission_id"], gpu),
)
conn.commit()
after = client.get("/api/leaderboard/339").get_json()["data"]["rankings"][gpu]
matches = [row for row in after if row["user_name"] == winner["user_name"]]
assert {row["submission_id"] for row in matches} == {990101, 990103}
assert len(matches) == 2
assert all(row["score"] == winner["score"] for row in matches)
original = next(row for row in matches if row["submission_id"] == 990101)
assert original["submission_count"] == winner["submission_count"] + 2
Loading