diff options
Diffstat (limited to 'Emby.Server.Implementations')
| -rw-r--r-- | Emby.Server.Implementations/Dto/DtoService.cs | 49 | ||||
| -rw-r--r-- | Emby.Server.Implementations/Library/LibraryManager.cs | 6 |
2 files changed, 43 insertions, 12 deletions
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index da0c52df5b..062c19a1d4 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -253,6 +253,18 @@ namespace Emby.Server.Implementations.Dto } } + // Batch-detect which videos own alternate versions to avoid the per-item alternate-version + // queries in MediaSourceCount. Videos absent from this set have a single media source. + IReadOnlySet<Guid>? alternateVersionItemIds = null; + if (options.ContainsField(ItemFields.MediaSourceCount)) + { + var versionItemIds = accessibleItems.OfType<Video>().Select(i => i.Id).ToList(); + if (versionItemIds.Count > 0) + { + alternateVersionItemIds = _libraryManager.GetItemsWithAlternateVersions(versionItemIds); + } + } + for (int index = 0; index < accessibleItems.Count; index++) { var item = accessibleItems[index]; @@ -267,7 +279,8 @@ namespace Emby.Server.Implementations.Dto playedCountBatch, artistsBatch, resumeDataBatch?.GetValueOrDefault(item.Id), - peopleBatch); + peopleBatch, + alternateVersionItemIds); if (item is LiveTvChannel tvChannel) { @@ -330,7 +343,8 @@ namespace Emby.Server.Implementations.Dto Dictionary<Guid, (int Played, int Total)>? playedCountBatch = null, IReadOnlyDictionary<string, MusicArtist[]>? artistsBatch = null, VersionResumeData? resumeData = null, - IReadOnlyDictionary<Guid, IReadOnlyList<PersonInfo>>? peopleBatch = null) + IReadOnlyDictionary<Guid, IReadOnlyList<PersonInfo>>? peopleBatch = null, + IReadOnlySet<Guid>? alternateVersionItemIds = null) { var dto = new BaseItemDto { @@ -399,7 +413,7 @@ namespace Emby.Server.Implementations.Dto AttachStudios(dto, item); } - AttachBasicFields(dto, item, owner, options, artistsBatch, user); + AttachBasicFields(dto, item, owner, options, artistsBatch, user, alternateVersionItemIds); if (options.ContainsField(ItemFields.CanDelete)) { @@ -984,7 +998,8 @@ namespace Emby.Server.Implementations.Dto /// <param name="options">The options.</param> /// <param name="artistsBatch">Optional pre-fetched artist lookup shared across a batch of items.</param> /// <param name="user">The user, for per-user values such as the accessible media source count.</param> - private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem? owner, DtoOptions options, IReadOnlyDictionary<string, MusicArtist[]>? artistsBatch = null, User? user = null) + /// <param name="alternateVersionItemIds">Optional pre-fetched set of item IDs that own alternate versions, shared across a batch of items.</param> + private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem? owner, DtoOptions options, IReadOnlyDictionary<string, MusicArtist[]>? artistsBatch = null, User? user = null, IReadOnlySet<Guid>? alternateVersionItemIds = null) { if (options.ContainsField(ItemFields.DateCreated)) { @@ -1298,15 +1313,25 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.MediaSourceCount)) { - // Match the per-user filtering of the media sources: versions the user cannot - // access are not selectable, so they must not count towards the badge either. - var mediaSourceCount = user is null - || (!video.PrimaryVersionId.HasValue && video.LinkedAlternateVersions.Length == 0 && !video.HasLocalAlternateVersions) - ? video.MediaSourceCount - : video.GetAllVersions().Count(v => v.Id.Equals(video.Id) || v.IsVisibleStandalone(user)); - if (mediaSourceCount != 1) + // A video with no primary version and no alternate versions always has a single + // media source. When the batch has already determined this item owns no alternate + // versions, skip the per-item alternate-version queries entirely (the common case). + var hasNoAlternateVersions = alternateVersionItemIds is not null + && !video.PrimaryVersionId.HasValue + && !alternateVersionItemIds.Contains(video.Id); + + if (!hasNoAlternateVersions) { - dto.MediaSourceCount = mediaSourceCount; + // Match the per-user filtering of the media sources: versions the user cannot + // access are not selectable, so they must not count towards the badge either. + var mediaSourceCount = user is null + || (!video.PrimaryVersionId.HasValue && video.LinkedAlternateVersions.Length == 0 && !video.HasLocalAlternateVersions) + ? video.MediaSourceCount + : video.GetAllVersions().Count(v => v.Id.Equals(video.Id) || v.IsVisibleStandalone(user)); + if (mediaSourceCount != 1) + { + dto.MediaSourceCount = mediaSourceCount; + } } } 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 @@ -2235,6 +2235,12 @@ namespace Emby.Server.Implementations.Library } /// <inheritdoc /> + public IReadOnlySet<Guid> GetItemsWithAlternateVersions(IReadOnlyList<Guid> itemIds) + { + return _linkedChildrenService.GetItemsWithAlternateVersions(itemIds); + } + + /// <inheritdoc /> public void UpsertLinkedChild(Guid parentId, Guid childId, MediaBrowser.Controller.Entities.LinkedChildType childType) { _linkedChildrenService.UpsertLinkedChild(parentId, childId, childType); |
