aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-06-12 08:09:10 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-06-12 08:35:30 +0200
commit0aeee8233bd0e602bd4523125d2c44b847d3fc7a (patch)
treeadfeb5bcf0f5f822598c94d784cfeaa8e6866840 /Emby.Server.Implementations
parent95de28cddad3344df85a452992bdc591b11552f7 (diff)
Fix performance
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Library/UserDataManager.cs50
1 files changed, 44 insertions, 6 deletions
diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs
index 4fda853bb1..bedaacee33 100644
--- a/Emby.Server.Implementations/Library/UserDataManager.cs
+++ b/Emby.Server.Implementations/Library/UserDataManager.cs
@@ -259,15 +259,53 @@ namespace Emby.Server.Implementations.Library
ArgumentNullException.ThrowIfNull(user);
var result = new Dictionary<Guid, VersionResumeData>();
+
+ // Candidate primaries: a directly queried version (PrimaryVersionId set) keeps its own data.
+ // Linked alternates are already known in memory; only the local-alternate existence check
+ // would otherwise hit the database (one query per item via Video.HasLocalAlternateVersions),
+ // so collect those ids and resolve them all in a single query below.
+ List<Video>? candidates = null;
+ List<Guid>? localProbeIds = null;
+ foreach (var item in items)
+ {
+ if (item is not Video video || video.PrimaryVersionId.HasValue)
+ {
+ continue;
+ }
+
+ (candidates ??= []).Add(video);
+
+ if (video.LinkedAlternateVersions.Length == 0)
+ {
+ (localProbeIds ??= []).Add(video.Id);
+ }
+ }
+
+ if (candidates is null)
+ {
+ return result;
+ }
+
+ HashSet<Guid>? withLocalAlternates = null;
+ if (localProbeIds is not null)
+ {
+ using var dbContext = _repository.CreateDbContext();
+ withLocalAlternates = dbContext.LinkedChildren
+ .Where(lc => lc.ChildType == Jellyfin.Database.Implementations.Entities.LinkedChildType.LocalAlternateVersion
+ && localProbeIds.Contains(lc.ParentId))
+ .Select(lc => lc.ParentId)
+ .Distinct()
+ .ToHashSet();
+ }
+
List<(Guid PrimaryId, IReadOnlyList<Video> Versions)>? versionGroups = null;
List<BaseItem>? allVersions = null;
- foreach (var item in items)
+ foreach (var video in candidates)
{
- // Only primary items aggregate over their versions; a directly queried version keeps its own data.
- if (item is not Video video
- || video.PrimaryVersionId.HasValue
- || (video.LinkedAlternateVersions.Length == 0 && !video.HasLocalAlternateVersions))
+ // Only items that actually have alternate versions aggregate over them.
+ if (video.LinkedAlternateVersions.Length == 0
+ && (withLocalAlternates is null || !withLocalAlternates.Contains(video.Id)))
{
continue;
}
@@ -278,7 +316,7 @@ namespace Emby.Server.Implementations.Library
continue;
}
- (versionGroups ??= []).Add((item.Id, versions));
+ (versionGroups ??= []).Add((video.Id, versions));
(allVersions ??= []).AddRange(versions);
}