From 2b4111d4fdd5042e49c51e693d0b15efe2ddc83f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Jun 2013 22:34:55 -0400 Subject: [PATCH] optimize ratings by caching --- .../HttpClientManager/HttpClientManager.cs | 2 +- .../Localization/ILocalizationManager.cs | 1 + .../Localization/LocalizationManager.cs | 107 ++++++++++++------ 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index ca18442a89..c29e2235df 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -121,7 +121,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30) { - throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true }; + throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true }; } using (var message = GetHttpRequestMessage(options)) diff --git a/MediaBrowser.Controller/Localization/ILocalizationManager.cs b/MediaBrowser.Controller/Localization/ILocalizationManager.cs index ecafec48a6..dde2f78781 100644 --- a/MediaBrowser.Controller/Localization/ILocalizationManager.cs +++ b/MediaBrowser.Controller/Localization/ILocalizationManager.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; using System.Collections.Generic; +using System.Threading.Tasks; namespace MediaBrowser.Controller.Localization { diff --git a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs index 1965531af9..89891a1629 100644 --- a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs +++ b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; using MoreLinq; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -28,6 +29,9 @@ namespace MediaBrowser.Server.Implementations.Localization /// private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + private readonly ConcurrentDictionary> _allParentalRatings = + new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); + /// /// Initializes a new instance of the class. /// @@ -92,7 +96,65 @@ namespace MediaBrowser.Server.Implementations.Localization /// IEnumerable{ParentalRating}. public IEnumerable GetParentalRatings() { - var path = GetRatingsFile(); + return GetParentalRatingsDictionary().Values.ToList(); + } + + /// + /// Gets the parental ratings dictionary. + /// + /// Dictionary{System.StringParentalRating}. + private Dictionary GetParentalRatingsDictionary() + { + var countryCode = _configurationManager.Configuration.MetadataCountryCode; + + if (string.IsNullOrEmpty(countryCode)) + { + countryCode = "us"; + } + + var ratings = GetRatings(countryCode); + + if (ratings == null) + { + ratings = GetRatings("us"); + } + + return ratings; + } + + /// + /// Gets the ratings. + /// + /// The country code. + private Dictionary GetRatings(string countryCode) + { + Dictionary value; + + if (!_allParentalRatings.TryGetValue(countryCode, out value)) + { + value = LoadRatings(countryCode); + + if (value != null) + { + _allParentalRatings.TryAdd(countryCode, value); + } + } + + return value; + } + + /// + /// Loads the ratings. + /// + /// The country code. + private Dictionary LoadRatings(string countryCode) + { + var path = GetRatingsFilePath(countryCode); + + if (string.IsNullOrEmpty(path)) + { + return null; + } return File.ReadAllLines(path).Select(i => { @@ -115,31 +177,14 @@ namespace MediaBrowser.Server.Implementations.Localization }) .Where(i => i != null) - .OrderBy(p => p.Value); - } - - /// - /// Gets the ratings file. - /// - /// System.String. - private string GetRatingsFile() - { - var countryCode = _configurationManager.Configuration.MetadataCountryCode; - - if (string.IsNullOrEmpty(countryCode)) - { - countryCode = "us"; - } - - return GetRatingsFile(countryCode).Result ?? GetRatingsFile("us").Result; + .ToDictionary(i => i.Name); } /// /// Gets the ratings file. /// /// The country code. - /// Task{System.String}. - private async Task GetRatingsFile(string countryCode) + private string GetRatingsFilePath(string countryCode) { countryCode = countryCode.ToLower(); @@ -166,9 +211,9 @@ namespace MediaBrowser.Server.Implementations.Localization Directory.CreateDirectory(parentPath); } - using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) + using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) { - await stream.CopyToAsync(fs).ConfigureAwait(false); + stream.CopyTo(fs); } } } @@ -179,9 +224,6 @@ namespace MediaBrowser.Server.Implementations.Localization /// /// Gets the rating level. /// - /// The rating. - /// System.Int32. - /// rating public int? GetRatingLevel(string rating) { if (string.IsNullOrEmpty(rating)) @@ -189,17 +231,18 @@ namespace MediaBrowser.Server.Implementations.Localization throw new ArgumentNullException("rating"); } - var ratingsDictionary = GetParentalRatings().ToDictionary(i => i.Name); + var ratingsDictionary = GetParentalRatingsDictionary(); - if (ratingsDictionary.ContainsKey(rating)) - return ratingsDictionary[rating].Value; + ParentalRating value; - var stripped = StripCountry(rating); + if (!ratingsDictionary.TryGetValue(rating, out value)) + { + var stripped = StripCountry(rating); - if (ratingsDictionary.ContainsKey(stripped)) - return ratingsDictionary[stripped].Value; + ratingsDictionary.TryGetValue(stripped, out value); + } - return null; + return value == null ? (int?)null : value.Value; } ///