Skip to content

Commit d106886

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

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

src/models/krate.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use crate::models::{
1717
};
1818
use crate::util::errors::{version_not_found, AppResult};
1919

20-
use crate::models::helpers::with_count::*;
2120
use crate::schema::*;
2221
use crate::sql::canon_crate_name;
2322

@@ -433,18 +432,32 @@ impl Crate {
433432
conn: &mut PgConnection,
434433
options: PaginationOptions,
435434
) -> QueryResult<(Vec<ReverseDependency>, i64)> {
435+
use diesel::dsl::{exists, not, sql};
436436
use diesel::sql_query;
437437
use diesel::sql_types::{BigInt, Integer};
438438

439439
let offset = options.offset().unwrap_or_default();
440-
let rows: Vec<WithCount<ReverseDependency>> =
440+
let rows: Vec<ReverseDependency> =
441441
sql_query(include_str!("krate_reverse_dependencies.sql"))
442442
.bind::<Integer, _>(self.id)
443443
.bind::<BigInt, _>(offset)
444444
.bind::<BigInt, _>(options.per_page)
445445
.load(conn)?;
446446

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

450463
/// 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)