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. --- Emby.Server.Implementations/Library/LibraryManager.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Emby.Server.Implementations/Library/LibraryManager.cs') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 19371f68d7..9bb962c504 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2234,6 +2234,12 @@ namespace Emby.Server.Implementations.Library return []; } + /// + public IReadOnlySet GetItemsWithAlternateVersions(IReadOnlyList itemIds) + { + return _linkedChildrenService.GetItemsWithAlternateVersions(itemIds); + } + /// public void UpsertLinkedChild(Guid parentId, Guid childId, MediaBrowser.Controller.Entities.LinkedChildType childType) { -- 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 'Emby.Server.Implementations/Library/LibraryManager.cs') 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