From c091ffdc6b2d8d4dd6f439d056c561bae7bd9a18 Mon Sep 17 00:00:00 2001 From: brandon Date: Fri, 7 Aug 2026 22:51:45 -0400 Subject: Batch alternate version detection in DtoService to remove MediaSourceCount N+1 Browsing a page of videos with the MediaSourceCount field ran one alternate version query per item, each opening a fresh DbContext. On a large library that turned a single page into hundreds of sequential round trips and made the Items endpoint take tens of seconds while holding a request thread the whole time. Detect which videos own alternate versions once per page with a single query, mirroring the existing people batch. Videos absent from that set have a single media source, so the per item lookups are skipped for the common case. Behavior is unchanged: a video with no alternates already resolved to a count of one. Adds a regression test asserting the count resolves from the batch and the per item lookups are never called. --- .../Item/LinkedChildrenService.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'Jellyfin.Server.Implementations') diff --git a/Jellyfin.Server.Implementations/Item/LinkedChildrenService.cs b/Jellyfin.Server.Implementations/Item/LinkedChildrenService.cs index 5f1d9bf87a..2452f8e3c6 100644 --- a/Jellyfin.Server.Implementations/Item/LinkedChildrenService.cs +++ b/Jellyfin.Server.Implementations/Item/LinkedChildrenService.cs @@ -59,6 +59,27 @@ public class LinkedChildrenService : ILinkedChildrenService .ToArray(); } + /// + public IReadOnlySet GetItemsWithAlternateVersions(IReadOnlyList itemIds) + { + if (itemIds.Count == 0) + { + return new HashSet(); + } + + using var dbContext = _dbProvider.CreateDbContext(); + + var parentIds = dbContext.LinkedChildren + .Where(lc => (lc.ChildType == DbLinkedChildType.LocalAlternateVersion + || lc.ChildType == DbLinkedChildType.LinkedAlternateVersion) + && itemIds.Contains(lc.ParentId)) + .Select(lc => lc.ParentId) + .Distinct() + .ToArray(); + + return parentIds.ToHashSet(); + } + /// public IReadOnlyDictionary FindArtists(IReadOnlyList artistNames) { -- cgit v1.2.3