From 740a10a4e3f85ffcfd26ec18263d4c78d4b14ecc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 10 Sep 2013 14:56:00 -0400 Subject: de-normalize item by name data. create counts during library scan for fast access. --- .../Library/LibraryManager.cs | 219 ++++++++++++--------- 1 file changed, 129 insertions(+), 90 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/LibraryManager.cs') diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d9ab75397..d017a5f7e 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -13,6 +13,7 @@ using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Library.Validators; using MediaBrowser.Server.Implementations.ScheduledTasks; using MoreLinq; using System; @@ -597,11 +598,11 @@ namespace MediaBrowser.Server.Implementations.Library /// The name. /// The cancellation token. /// if set to true [allow slow providers]. - /// if set to true [force creation]. + /// if set to true [force creation]. /// Task{Person}. - private Task GetPerson(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool forceCreation = false) + private Task GetPerson(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false) { - return GetItemByName(ConfigurationManager.ApplicationPaths.PeoplePath, name, cancellationToken, allowSlowProviders, forceCreation); + return GetItemByName(ConfigurationManager.ApplicationPaths.PeoplePath, name, cancellationToken, allowSlowProviders, refreshMetadata); } /// @@ -612,7 +613,20 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{Studio}. public Task GetStudio(string name, bool allowSlowProviders = false) { - return GetItemByName(ConfigurationManager.ApplicationPaths.StudioPath, name, CancellationToken.None, allowSlowProviders); + return GetStudio(name, CancellationToken.None, allowSlowProviders); + } + + /// + /// Gets the studio. + /// + /// The name. + /// The cancellation token. + /// if set to true [allow slow providers]. + /// if set to true [refresh metadata]. + /// Task{Studio}. + internal Task GetStudio(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false) + { + return GetItemByName(ConfigurationManager.ApplicationPaths.StudioPath, name, cancellationToken, allowSlowProviders, refreshMetadata); } /// @@ -623,7 +637,20 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{Genre}. public Task GetGenre(string name, bool allowSlowProviders = false) { - return GetItemByName(ConfigurationManager.ApplicationPaths.GenrePath, name, CancellationToken.None, allowSlowProviders); + return GetGenre(name, CancellationToken.None, allowSlowProviders); + } + + /// + /// Gets the genre. + /// + /// The name. + /// The cancellation token. + /// if set to true [allow slow providers]. + /// if set to true [refresh metadata]. + /// Task{Genre}. + internal Task GetGenre(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false) + { + return GetItemByName(ConfigurationManager.ApplicationPaths.GenrePath, name, cancellationToken, allowSlowProviders, refreshMetadata); } /// @@ -634,7 +661,20 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{MusicGenre}. public Task GetMusicGenre(string name, bool allowSlowProviders = false) { - return GetItemByName(ConfigurationManager.ApplicationPaths.MusicGenrePath, name, CancellationToken.None, allowSlowProviders); + return GetMusicGenre(name, CancellationToken.None, allowSlowProviders); + } + + /// + /// Gets the music genre. + /// + /// The name. + /// The cancellation token. + /// if set to true [allow slow providers]. + /// if set to true [refresh metadata]. + /// Task{MusicGenre}. + internal Task GetMusicGenre(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false) + { + return GetItemByName(ConfigurationManager.ApplicationPaths.MusicGenrePath, name, cancellationToken, allowSlowProviders, refreshMetadata); } /// @@ -645,7 +685,20 @@ namespace MediaBrowser.Server.Implementations.Library /// Task{GameGenre}. public Task GetGameGenre(string name, bool allowSlowProviders = false) { - return GetItemByName(ConfigurationManager.ApplicationPaths.GameGenrePath, name, CancellationToken.None, allowSlowProviders); + return GetGameGenre(name, CancellationToken.None, allowSlowProviders); + } + + /// + /// Gets the game genre. + /// + /// The name. + /// The cancellation token. + /// if set to true [allow slow providers]. + /// if set to true [refresh metadata]. + /// Task{GameGenre}. + internal Task GetGameGenre(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false) + { + return GetItemByName(ConfigurationManager.ApplicationPaths.GameGenrePath, name, cancellationToken, allowSlowProviders, refreshMetadata); } /// @@ -665,11 +718,11 @@ namespace MediaBrowser.Server.Implementations.Library /// The name. /// The cancellation token. /// if set to true [allow slow providers]. - /// if set to true [force creation]. + /// if set to true [force creation]. /// Task{Artist}. - private Task GetArtist(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool forceCreation = false) + internal Task GetArtist(string name, CancellationToken cancellationToken, bool allowSlowProviders = false, bool refreshMetadata = false) { - return GetItemByName(ConfigurationManager.ApplicationPaths.ArtistsPath, name, cancellationToken, allowSlowProviders, forceCreation); + return GetItemByName(ConfigurationManager.ApplicationPaths.ArtistsPath, name, cancellationToken, allowSlowProviders, refreshMetadata); } /// @@ -707,11 +760,11 @@ namespace MediaBrowser.Server.Implementations.Library /// The name. /// The cancellation token. /// if set to true [allow slow providers]. - /// if set to true [force creation]. + /// if set to true [force creation]. /// Task{``0}. /// /// - private async Task GetItemByName(string path, string name, CancellationToken cancellationToken, bool allowSlowProviders = true, bool forceCreation = false) + private async Task GetItemByName(string path, string name, CancellationToken cancellationToken, bool allowSlowProviders = true, bool refreshMetadata = false) where T : BaseItem, new() { if (string.IsNullOrEmpty(path)) @@ -730,11 +783,25 @@ namespace MediaBrowser.Server.Implementations.Library if (!_itemsByName.TryGetValue(key, out obj)) { - obj = await CreateItemByName(path, name, cancellationToken, allowSlowProviders).ConfigureAwait(false); + var tuple = CreateItemByName(path, name, cancellationToken); + + obj = tuple.Item2; _itemsByName.AddOrUpdate(key, obj, (keyName, oldValue) => obj); + + try + { + await obj.RefreshMetadata(cancellationToken, tuple.Item1, allowSlowProviders: allowSlowProviders).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + BaseItem removed; + _itemsByName.TryRemove(key, out removed); + + throw; + } } - else if (forceCreation) + else if (refreshMetadata) { await obj.RefreshMetadata(cancellationToken, false, allowSlowProviders: allowSlowProviders).ConfigureAwait(false); } @@ -749,10 +816,9 @@ namespace MediaBrowser.Server.Implementations.Library /// The path. /// The name. /// The cancellation token. - /// if set to true [allow slow providers]. /// Task{``0}. /// Path not created: + path - private async Task CreateItemByName(string path, string name, CancellationToken cancellationToken, bool allowSlowProviders = true) + private Tuple CreateItemByName(string path, string name, CancellationToken cancellationToken) where T : BaseItem, new() { cancellationToken.ThrowIfCancellationRequested(); @@ -783,6 +849,7 @@ namespace MediaBrowser.Server.Implementations.Library var id = path.GetMBId(type); var item = RetrieveItem(id) as T; + if (item == null) { item = new T @@ -796,16 +863,10 @@ namespace MediaBrowser.Server.Implementations.Library isNew = true; } - cancellationToken.ThrowIfCancellationRequested(); - // Set this now so we don't cause additional file system access during provider executions item.ResetResolveArgs(fileInfo); - await item.RefreshMetadata(cancellationToken, isNew, allowSlowProviders: allowSlowProviders).ConfigureAwait(false); - - cancellationToken.ThrowIfCancellationRequested(); - - return item; + return new Tuple(isNew, item); } /// @@ -884,75 +945,53 @@ namespace MediaBrowser.Server.Implementations.Library /// The cancellation token. /// The progress. /// Task. - public async Task ValidateArtists(CancellationToken cancellationToken, IProgress progress) + public Task ValidateArtists(CancellationToken cancellationToken, IProgress progress) { - const int maxTasks = 25; - - var tasks = new List(); - - var artists = RootFolder.RecursiveChildren - .OfType