diff options
Diffstat (limited to 'MediaBrowser.LocalMetadata/Savers')
| -rw-r--r-- | MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs index 025a815247..b0f51aec71 100644 --- a/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -6,7 +7,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; -using Jellyfin.Data.Enums; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; @@ -467,41 +467,62 @@ namespace MediaBrowser.LocalMetadata.Savers } /// <summary> - /// ADd linked children. + /// Add linked children. /// </summary> /// <param name="item">The item.</param> /// <param name="writer">The xml writer.</param> /// <param name="pluralNodeName">The plural node name.</param> /// <param name="singularNodeName">The singular node name.</param> /// <returns>The task object representing the asynchronous operation.</returns> - private static async Task AddLinkedChildren(Folder item, XmlWriter writer, string pluralNodeName, string singularNodeName) + private async Task AddLinkedChildren(Folder item, XmlWriter writer, string pluralNodeName, string singularNodeName) { - var items = item.LinkedChildren + var linkedChildren = item.LinkedChildren .Where(i => i.Type == LinkedChildType.Manual) .ToList(); - if (items.Count == 0) + if (linkedChildren.Count == 0) { return; } - await writer.WriteStartElementAsync(null, pluralNodeName, null).ConfigureAwait(false); + // Batch-resolve all ItemIds to paths in a single query to avoid an N+1 round-trip per linked child + var idsToResolve = new HashSet<Guid>(); + foreach (var link in linkedChildren) + { + if (link.ItemId.HasValue && !link.ItemId.Value.Equals(Guid.Empty)) + { + idsToResolve.Add(link.ItemId.Value); + } + } - foreach (var link in items) + Dictionary<Guid, string?>? pathById = null; + if (idsToResolve.Count > 0) { - if (!string.IsNullOrWhiteSpace(link.Path) || !string.IsNullOrWhiteSpace(link.LibraryItemId)) + var batched = LibraryManager.GetItemList(new InternalItemsQuery { - await writer.WriteStartElementAsync(null, singularNodeName, null).ConfigureAwait(false); - if (!string.IsNullOrWhiteSpace(link.Path)) - { - await writer.WriteElementStringAsync(null, "Path", null, link.Path).ConfigureAwait(false); - } + ItemIds = [.. idsToResolve] + }); + pathById = new Dictionary<Guid, string?>(batched.Count); + foreach (var batchedItem in batched) + { + pathById[batchedItem.Id] = batchedItem.Path; + } + } - if (!string.IsNullOrWhiteSpace(link.LibraryItemId)) - { - await writer.WriteElementStringAsync(null, "ItemId", null, link.LibraryItemId).ConfigureAwait(false); - } + await writer.WriteStartElementAsync(null, pluralNodeName, null).ConfigureAwait(false); + + foreach (var link in linkedChildren) + { + string? path = null; + if (pathById is not null && link.ItemId.HasValue && pathById.TryGetValue(link.ItemId.Value, out var resolvedPath)) + { + path = resolvedPath; + } + if (!string.IsNullOrWhiteSpace(path)) + { + await writer.WriteStartElementAsync(null, singularNodeName, null).ConfigureAwait(false); + await writer.WriteElementStringAsync(null, "Path", null, path).ConfigureAwait(false); await writer.WriteEndElementAsync().ConfigureAwait(false); } } |
