Simplify BuildRepository.allByWeaponId

This commit is contained in:
Kalle 2026-04-09 20:37:11 +03:00
parent d872be4d75
commit b3b5e1ff96

View File

@ -320,65 +320,23 @@ export async function allByWeaponId(
const { limit, sortAbilities: shouldSortAbilities = false } = options;
const weaponIds = weaponIdToArrayWithAlts(weaponId);
let rows: Awaited<ReturnType<typeof buildsByWeaponIdQuery>>;
// For weapons with alts, run separate queries and merge.
// This allows each query to use the covering index for ordering,
// which is ~6x faster than using IN with multiple values.
const allResults = await Promise.all(
weaponIds.map((id) => buildsByWeaponIdQuery(id, limit)),
);
if (weaponIds.length === 1) {
rows = await buildsByWeaponIdQuery(weaponIds[0], limit);
} else {
// For weapons with alts, run separate queries and merge.
// This allows each query to use the covering index for ordering,
// which is ~6x faster than using IN with multiple values.
const allResults = await Promise.all(
weaponIds.map((id) => buildsByWeaponIdQuery(id, limit)),
);
const seenBuildIds = new Set<number>();
type BuildRow = Awaited<ReturnType<typeof buildsByWeaponIdQuery>>[number];
const merged: BuildRow[] = [];
// Merge results maintaining sort order (tier asc, isTop500 desc, updatedAt desc)
// Since each query returns sorted results, we can interleave them
const pointers = allResults.map(() => 0);
while (merged.length < limit) {
let bestIdx = -1;
let bestRow: BuildRow | null = null;
for (let i = 0; i < allResults.length; i++) {
while (
pointers[i] < allResults[i].length &&
seenBuildIds.has(allResults[i][pointers[i]].id)
) {
pointers[i]++;
}
if (pointers[i] >= allResults[i].length) continue;
const row = allResults[i][pointers[i]];
if (
!bestRow ||
row.bwTier < bestRow.bwTier ||
(row.bwTier === bestRow.bwTier &&
row.bwIsTop500 > bestRow.bwIsTop500) ||
(row.bwTier === bestRow.bwTier &&
row.bwIsTop500 === bestRow.bwIsTop500 &&
row.bwUpdatedAt > bestRow.bwUpdatedAt)
) {
bestIdx = i;
bestRow = row;
}
}
if (bestIdx === -1 || !bestRow) break;
seenBuildIds.add(bestRow.id);
merged.push(bestRow);
pointers[bestIdx]++;
}
rows = merged;
}
const rows = R.pipe(
allResults.flat(),
R.sortBy(
(row) => row.bwTier,
[(row) => row.bwIsTop500, "desc"],
[(row) => row.bwUpdatedAt, "desc"],
),
R.uniqueBy((row) => row.id),
R.take(limit),
);
return rows.map((row) => {
const abilities = dbAbilitiesToArrayOfArrays(row.abilities);