aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
authorbrandon <brandon@clinger.dev>2026-08-07 22:51:45 -0400
committerbrandon <brandon@clinger.dev>2026-08-07 22:51:45 -0400
commitc091ffdc6b2d8d4dd6f439d056c561bae7bd9a18 (patch)
tree139761baa65d22dc99f8b1ecd3795265836f2674 /MediaBrowser.Controller
parent70ffd25b505fff4423d7aab5386d46e327713708 (diff)
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.
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs8
-rw-r--r--MediaBrowser.Controller/Persistence/ILinkedChildrenService.cs9
2 files changed, 17 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 5eae6e103f..f6bd948b99 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -256,6 +256,14 @@ namespace MediaBrowser.Controller.Library
IEnumerable<Video> GetLinkedAlternateVersions(Video video);
/// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="itemIds">The item IDs to check.</param>
+ /// <returns>The set of item IDs that have alternate versions.</returns>
+ IReadOnlySet<Guid> GetItemsWithAlternateVersions(IReadOnlyList<Guid> itemIds);
+
+ /// <summary>
/// Creates or updates a LinkedChild entry linking a parent to a child item.
/// </summary>
/// <param name="parentId">The parent item ID.</param>
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
@@ -20,6 +20,15 @@ public interface ILinkedChildrenService
IReadOnlyList<Guid> GetLinkedChildrenIds(Guid parentId, int? childType = null);
/// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="itemIds">The item IDs to check.</param>
+ /// <returns>The set of item IDs that have alternate versions.</returns>
+ IReadOnlySet<Guid> GetItemsWithAlternateVersions(IReadOnlyList<Guid> itemIds);
+
+ /// <summary>
/// Gets all artist matches from the database.
/// </summary>
/// <param name="artistNames">The names of the artists.</param>