diff options
| author | Niels van Velzen <nielsvanvelzen@users.noreply.github.com> | 2026-05-03 21:56:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-03 21:56:34 +0200 |
| commit | 6e22075a63432aae48859cf9c67fde158dc80d2e (patch) | |
| tree | c3a33238cc56857d8e3daa56db01f290118c9215 /MediaBrowser.Controller/Library/ILibraryManager.cs | |
| parent | d9ced0d6399c82ddad9e983605bb0d828a608e63 (diff) | |
| parent | d68d0fa96267ad96eaa5a0ba37e072f59a71442a (diff) | |
Merge pull request #16062 from Shadowghost/perf-rebased
Query Performance Improvements
Diffstat (limited to 'MediaBrowser.Controller/Library/ILibraryManager.cs')
| -rw-r--r-- | MediaBrowser.Controller/Library/ILibraryManager.cs | 114 |
1 files changed, 112 insertions, 2 deletions
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index df1c98f3f7..5c391098d3 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -20,6 +20,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Querying; using Episode = MediaBrowser.Controller.Entities.TV.Episode; using Genre = MediaBrowser.Controller.Entities.Genre; +using LinkedChildType = MediaBrowser.Controller.Entities.LinkedChildType; using Person = MediaBrowser.Controller.Entities.Person; namespace MediaBrowser.Controller.Library @@ -58,11 +59,29 @@ namespace MediaBrowser.Controller.Library /// <param name="fileInfo">The file information.</param> /// <param name="parent">The parent.</param> /// <param name="directoryService">An instance of <see cref="IDirectoryService"/>.</param> + /// <param name="collectionType">The collection type of the library containing this item.</param> /// <returns>BaseItem.</returns> BaseItem? ResolvePath( FileSystemMetadata fileInfo, Folder? parent = null, - IDirectoryService? directoryService = null); + IDirectoryService? directoryService = null, + CollectionType? collectionType = null); + + /// <summary> + /// Resolves a video file as an alternate version of a primary video, ensuring the result + /// has the same concrete type as the primary (e.g. Movie instead of generic Video). + /// Also cleans up any existing item with the wrong type from a previous scan. + /// </summary> + /// <param name="path">The file path of the alternate version.</param> + /// <param name="expectedVideoType">The expected concrete type (same as the primary video).</param> + /// <param name="parent">The parent folder.</param> + /// <param name="collectionType">The collection type of the library.</param> + /// <returns>A correctly-typed Video, or null if resolution fails.</returns> + Video? ResolveAlternateVersion( + string path, + Type expectedVideoType, + Folder? parent, + CollectionType? collectionType); /// <summary> /// Resolves a set of files into a list of BaseItem. @@ -214,6 +233,30 @@ namespace MediaBrowser.Controller.Library Task<IEnumerable<Video>> GetIntros(BaseItem item, User user); /// <summary> + /// Gets the IDs of local alternate versions for a video. + /// Local alternate versions are alternate quality versions at different file paths. + /// </summary> + /// <param name="video">The video item.</param> + /// <returns>Enumerable of alternate version item IDs.</returns> + IEnumerable<Guid> GetLocalAlternateVersionIds(Video video); + + /// <summary> + /// Gets the linked alternate versions for a video. + /// Linked alternate versions are different items representing the same content (e.g., Director's Cut). + /// </summary> + /// <param name="video">The video item.</param> + /// <returns>Enumerable of linked Video items.</returns> + IEnumerable<Video> GetLinkedAlternateVersions(Video video); + + /// <summary> + /// Creates or updates a LinkedChild entry linking a parent to a child item. + /// </summary> + /// <param name="parentId">The parent item ID.</param> + /// <param name="childId">The child item ID.</param> + /// <param name="childType">The type of linked child relationship.</param> + void UpsertLinkedChild(Guid parentId, Guid childId, LinkedChildType childType); + + /// <summary> /// Adds the parts. /// </summary> /// <param name="rules">The rules.</param> @@ -348,8 +391,9 @@ namespace MediaBrowser.Controller.Library /// Deletes items that are not having any children like Actors. /// </summary> /// <param name="items">Items to delete.</param> + /// <param name="deleteSourceFiles">Whether to delete source media files on disk. Defaults to false.</param> /// <remarks>In comparison to <see cref="DeleteItem(BaseItem, DeleteOptions, BaseItem, bool)"/> this method skips a lot of steps assuming there are no children to recusively delete nor does it define the special handling for channels and alike.</remarks> - public void DeleteItemsUnsafeFast(IEnumerable<BaseItem> items); + public void DeleteItemsUnsafeFast(IReadOnlyCollection<BaseItem> items, bool deleteSourceFiles = false); /// <summary> /// Deletes the item. @@ -601,6 +645,20 @@ namespace MediaBrowser.Controller.Library IReadOnlyList<string> GetNextUpSeriesKeys(InternalItemsQuery query, IReadOnlyCollection<BaseItem> parents, DateTime dateCutoff); /// <summary> + /// Gets next up episodes for multiple series in a single batched query. + /// </summary> + /// <param name="query">The query filter.</param> + /// <param name="seriesKeys">The series presentation unique keys to query.</param> + /// <param name="includeSpecials">Whether to include specials for aired episode order sorting.</param> + /// <param name="includeWatchedForRewatching">Whether to include watched episodes for rewatching mode.</param> + /// <returns>A dictionary mapping series key to batch result.</returns> + IReadOnlyDictionary<string, MediaBrowser.Controller.Persistence.NextUpEpisodeBatchResult> GetNextUpEpisodesBatch( + InternalItemsQuery query, + IReadOnlyList<string> seriesKeys, + bool includeSpecials, + bool includeWatchedForRewatching); + + /// <summary> /// Gets the items result. /// </summary> /// <param name="query">The query.</param> @@ -649,6 +707,42 @@ namespace MediaBrowser.Controller.Library ItemCounts GetItemCounts(InternalItemsQuery query); + /// <summary> + /// Gets item counts for a "by-name" item using an optimized query path. + /// </summary> + /// <param name="kind">The kind of the name item.</param> + /// <param name="id">The ID of the name item.</param> + /// <param name="relatedItemKinds">The item kinds to count.</param> + /// <param name="user">The user for access filtering.</param> + /// <returns>The item counts grouped by type.</returns> + ItemCounts GetItemCountsForNameItem(BaseItemKind kind, Guid id, BaseItemKind[] relatedItemKinds, User? user); + + /// <summary> + /// Batch-fetches child counts for multiple parent folders. + /// Returns the count of immediate children (non-recursive) for each parent. + /// </summary> + /// <param name="parentIds">The list of parent folder IDs.</param> + /// <param name="userId">The user ID for access filtering.</param> + /// <returns>Dictionary mapping parent ID to child count.</returns> + Dictionary<Guid, int> GetChildCountBatch(IReadOnlyList<Guid> parentIds, Guid? userId); + + /// <summary> + /// Batch-fetches played and total counts for multiple folder items. + /// Avoids N+1 queries when building DTOs for lists of folder items. + /// </summary> + /// <param name="folderIds">The list of folder item IDs.</param> + /// <param name="user">The user for access filtering and played status.</param> + /// <returns>Dictionary mapping folder ID to (Played count, Total count).</returns> + Dictionary<Guid, (int Played, int Total)> GetPlayedAndTotalCountBatch(IReadOnlyList<Guid> folderIds, User user); + + /// <summary> + /// Configures the query with user access settings including TopParentIds for library access. + /// Call this before passing a query to methods that need user access filtering. + /// </summary> + /// <param name="query">The query to configure.</param> + /// <param name="user">The user to configure access for.</param> + void ConfigureUserAccess(InternalItemsQuery query, User user); + Task RunMetadataSavers(BaseItem item, ItemUpdateType updateReason); BaseItem GetParentItem(Guid? parentId, Guid? userId); @@ -667,5 +761,21 @@ namespace MediaBrowser.Controller.Library /// <param name="virtualFolderPath">The path to the virtualfolder.</param> /// <param name="pathInfo">The new virtualfolder.</param> public void CreateShortcut(string virtualFolderPath, MediaPathInfo pathInfo); + + /// <summary> + /// Re-routes LinkedChildren references from one child to another. + /// Used when video versions change to maintain playlist/BoxSet integrity. + /// </summary> + /// <param name="fromChildId">The child ID to re-route from.</param> + /// <param name="toChildId">The child ID to re-route to.</param> + /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> + Task RerouteLinkedChildReferencesAsync(Guid fromChildId, Guid toChildId); + + /// <summary> + /// Gets legacy query filters for filtering UI. + /// </summary> + /// <param name="query">The query filter.</param> + /// <returns>Aggregated filter values.</returns> + QueryFiltersLegacy GetQueryFiltersLegacy(InternalItemsQuery query); } } |
