Skip to content

Commit 611b4e8

Browse files
committed
Improve the performance of reverse dependencies using the default_versions
1 parent 39964df commit 611b4e8

File tree

2 files changed

+33
-30
lines changed

2 files changed

+33
-30
lines changed

src/models/krate.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,18 +433,32 @@ impl Crate {
433433
conn: &mut PgConnection,
434434
options: PaginationOptions,
435435
) -> QueryResult<(Vec<ReverseDependency>, i64)> {
436+
use diesel::dsl::{exists, not, sql};
436437
use diesel::sql_query;
437438
use diesel::sql_types::{BigInt, Integer};
438439

439440
let offset = options.offset().unwrap_or_default();
440-
let rows: Vec<WithCount<ReverseDependency>> =
441+
let rows: Vec<ReverseDependency> =
441442
sql_query(include_str!("krate_reverse_dependencies.sql"))
442443
.bind::<Integer, _>(self.id)
443444
.bind::<BigInt, _>(offset)
444445
.bind::<BigInt, _>(options.per_page)
445446
.load(conn)?;
446447

447-
Ok(rows.records_and_total())
448+
let dep_versions_subq = dependencies::table
449+
.filter(dependencies::crate_id.eq(self.id))
450+
.select(dependencies::version_id);
451+
let yanked_subq = versions::table
452+
.filter(versions::id.eq(default_versions::version_id))
453+
.filter(versions::yanked)
454+
.select(sql::<Integer>("1"));
455+
let total = default_versions::table
456+
.filter(default_versions::version_id.eq_any(dep_versions_subq))
457+
.filter(not(exists(yanked_subq)))
458+
.count()
459+
.get_result(conn)?;
460+
461+
Ok((rows, total))
448462
}
449463

450464
/// Gather all the necessary data to write an index metadata file
Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
11
SELECT
2-
dependencies.*, crate_downloads, crate_name, total
2+
dependencies.*, crate_downloads, crate_name
33
FROM (
4-
-- Apply pagination to the crates
5-
SELECT *, COUNT(*) OVER () as total FROM (
6-
SELECT
7-
crate_downloads.downloads AS crate_downloads,
8-
crates.name AS crate_name,
9-
versions.id AS version_id
10-
FROM
11-
-- We only want the crates whose *max* version is dependent, so we join on a
12-
-- subselect that includes the versions with their ordinal position
13-
(
14-
SELECT DISTINCT ON (crate_id)
15-
crate_id, semver_no_prerelease, id
4+
SELECT
5+
crate_downloads.downloads AS crate_downloads,
6+
crates.name AS crate_name,
7+
version_id
8+
FROM default_versions
9+
INNER JOIN crates
10+
ON crates.id = default_versions.crate_id
11+
INNER JOIN crate_downloads using (crate_id)
12+
WHERE version_id IN (SELECT version_id FROM dependencies WHERE crate_id = $1)
13+
AND NOT EXISTS (
14+
SELECT 1
1615
FROM versions
17-
WHERE NOT yanked
18-
ORDER BY
19-
crate_id,
20-
semver_no_prerelease DESC NULLS LAST,
21-
id DESC
22-
) versions
23-
INNER JOIN crates
24-
ON crates.id = versions.crate_id
25-
INNER JOIN crate_downloads
26-
ON crate_downloads.crate_id = crates.id
27-
WHERE versions.id IN (SELECT version_id FROM dependencies WHERE crate_id = $1)
28-
) c
29-
ORDER BY
30-
crate_downloads DESC,
31-
crate_name ASC
16+
WHERE id = version_id and yanked
17+
)
3218
) crates
3319
-- Multiple dependencies can exist, we only want first one
3420
CROSS JOIN LATERAL (
@@ -38,5 +24,8 @@ CROSS JOIN LATERAL (
3824
ORDER BY id ASC
3925
LIMIT 1
4026
) dependencies
27+
ORDER BY
28+
crate_downloads DESC,
29+
crate_name ASC
4130
OFFSET $2
4231
LIMIT $3

0 commit comments

Comments
 (0)