mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-01 00:24:13 -05:00
Simplify BuildRepository.allByWeaponId
This commit is contained in:
parent
d872be4d75
commit
b3b5e1ff96
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user