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. --- MediaBrowser.Controller/Persistence/ILinkedChildrenService.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'MediaBrowser.Controller/Persistence') diff --git a/MediaBrowser.Controller/Persistence/ILinkedChildrenService.cs b/MediaBrowser.Controller/Persistence/ILinkedChildrenService.cs index a4614fc125..c1fe3231f4 100644 --- a/MediaBrowser.Controller/Persistence/ILinkedChildrenService.cs +++ b/MediaBrowser.Controller/Persistence/ILinkedChildrenService.cs @@ -19,6 +19,15 @@ public interface ILinkedChildrenService /// List of child item IDs. IReadOnlyList GetLinkedChildrenIds(Guid parentId, int? childType = null); + /// + /// Gets, in a single query, the subset of the supplied items that own at least one alternate + /// version (local or linked). Items absent from the result have no alternate versions, so their + /// media source count is one. + /// + /// The item IDs to check. + /// The set of item IDs that have alternate versions. + IReadOnlySet GetItemsWithAlternateVersions(IReadOnlyList itemIds); + /// /// Gets all artist matches from the database. /// -- cgit v1.2.3 From 10d108a1f453c0972b3059e10bb9b13bbcb34f63 Mon Sep 17 00:00:00 2001 From: brandon Date: Sat, 8 Aug 2026 12:33:11 -0400 Subject: Address review on MediaSourceCount batching Rename GetItemsWithAlternateVersions to GetItemIdsWithAlternateVersions across the interfaces and implementations since it returns ids. Return the hashset straight from the query instead of materializing an array first. Rename the DtoService guard to mayHaveAlternateVersions and invert it so the computed path is the explicit case. Assert the media source count value in the batch skip test and add a test covering an item that is in the returned set still resolving to the correct count. --- Emby.Server.Implementations/Dto/DtoService.cs | 18 +++++---- .../Library/LibraryManager.cs | 4 +- .../Item/LinkedChildrenService.cs | 8 ++-- MediaBrowser.Controller/Library/ILibraryManager.cs | 2 +- .../Persistence/ILinkedChildrenService.cs | 2 +- .../Dto/DtoServiceImageInheritanceTests.cs | 47 ++++++++++++++++++++-- 6 files changed, 61 insertions(+), 20 deletions(-) (limited to 'MediaBrowser.Controller/Persistence') diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 062c19a1d4..6fa057702c 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -261,7 +261,7 @@ namespace Emby.Server.Implementations.Dto var versionItemIds = accessibleItems.OfType