From 78dacf68503b87ca114aade8b4eb77f880bb6d63 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 22 Feb 2014 00:53:29 -0800 Subject: [PATCH] Fixed: Performance issues when processing results from indexers (RSS/Search) --- .../Configuration/ConfigRepository.cs | 4 +-- .../Datastore/BasicRepository.cs | 3 +-- .../DecisionEngine/DownloadDecisionMaker.cs | 5 ++-- .../QualityUpgradableSpecification.cs | 1 - .../AcceptableSizeSpecification.cs | 23 ++++++---------- src/NzbDrone.Core/Jobs/JobRepository.cs | 2 +- .../Metadata/Files/MetadataFileRepository.cs | 2 +- .../Qualities/QualityDefinitionRepository.cs | 2 +- src/NzbDrone.Core/Tv/EpisodeRepository.cs | 27 ++++++++++++++----- src/NzbDrone.Core/Tv/EpisodeService.cs | 2 -- src/NzbDrone.Core/Tv/SeriesRepository.cs | 18 ++++++++----- src/NzbDrone.Core/Tv/SeriesService.cs | 2 -- 12 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/NzbDrone.Core/Configuration/ConfigRepository.cs b/src/NzbDrone.Core/Configuration/ConfigRepository.cs index 0c21b2793..7aef7d26f 100644 --- a/src/NzbDrone.Core/Configuration/ConfigRepository.cs +++ b/src/NzbDrone.Core/Configuration/ConfigRepository.cs @@ -21,9 +21,7 @@ namespace NzbDrone.Core.Configuration public Config Get(string key) { - return Query.SingleOrDefault(c => c.Key == key); + return Query.Where(c => c.Key == key).SingleOrDefault(); } - - } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Datastore/BasicRepository.cs b/src/NzbDrone.Core/Datastore/BasicRepository.cs index 6f6ed553e..74354e28f 100644 --- a/src/NzbDrone.Core/Datastore/BasicRepository.cs +++ b/src/NzbDrone.Core/Datastore/BasicRepository.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; -using System.Security.Cryptography.X509Certificates; using Marr.Data; using Marr.Data.QGen; using NzbDrone.Core.Datastore.Events; @@ -74,7 +73,7 @@ namespace NzbDrone.Core.Datastore public TModel Get(int id) { - var model = DataMapper.Query().SingleOrDefault(c => c.Id == id); + var model = Query.Where(c => c.Id == id).SingleOrDefault(); if (model == null) { diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index b8b77c5a3..bae6f3d60 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -23,7 +23,7 @@ namespace NzbDrone.Core.DecisionEngine private readonly IParsingService _parsingService; private readonly Logger _logger; - public DownloadDecisionMaker(IEnumerable specifications, IParsingService parsingService, Logger logger) + public DownloadDecisionMaker(IEnumerable specifications, IParsingService parsingService, Logger logger) { _specifications = specifications; _parsingService = parsingService; @@ -100,13 +100,12 @@ namespace NzbDrone.Core.DecisionEngine yield return decision; } } - } private DownloadDecision GetDecisionForReport(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria = null) { var reasons = _specifications.Select(c => EvaluateSpec(c, remoteEpisode, searchCriteria)) - .Where(c => !string.IsNullOrWhiteSpace(c)); + .Where(c => !string.IsNullOrWhiteSpace(c)); return new DownloadDecision(remoteEpisode, reasons.ToArray()); } diff --git a/src/NzbDrone.Core/DecisionEngine/QualityUpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/QualityUpgradableSpecification.cs index 3330be7ab..aae2a6d6b 100644 --- a/src/NzbDrone.Core/DecisionEngine/QualityUpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/QualityUpgradableSpecification.cs @@ -1,6 +1,5 @@ using NLog; using NzbDrone.Core.Qualities; -using NzbDrone.Core.Tv; namespace NzbDrone.Core.DecisionEngine { diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs index 8069e8201..8cd175703 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs @@ -27,7 +27,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { - _logger.Trace("Beginning size check for: {0}", subject); var quality = subject.ParsedEpisodeInfo.Quality.Quality; @@ -45,21 +44,17 @@ namespace NzbDrone.Core.DecisionEngine.Specifications } var qualityDefinition = _qualityDefinitionService.Get(quality); + var minSize = qualityDefinition.MinSize.Megabytes(); + //Multiply maxSize by Series.Runtime + minSize = minSize * subject.Series.Runtime * subject.Episodes.Count; + + //If the parsed size is smaller than minSize we don't want it + if (subject.Release.Size < minSize) { - var minSize = qualityDefinition.MinSize.Megabytes(); - - //Multiply maxSize by Series.Runtime - minSize = minSize * subject.Series.Runtime * subject.Episodes.Count; - - //If the parsed size is smaller than minSize we don't want it - if (subject.Release.Size < minSize) - { - _logger.Trace("Item: {0}, Size: {1} is smaller than minimum allowed size ({2}), rejecting.", subject, subject.Release.Size, minSize); - return false; - } + _logger.Trace("Item: {0}, Size: {1} is smaller than minimum allowed size ({2}), rejecting.", subject, subject.Release.Size, minSize); + return false; } - if (qualityDefinition.MaxSize == 0) { _logger.Trace("Max size is 0 (unlimited) - skipping check."); @@ -84,10 +79,8 @@ namespace NzbDrone.Core.DecisionEngine.Specifications return false; } } - _logger.Trace("Item: {0}, meets size constraints.", subject); return true; } - } } diff --git a/src/NzbDrone.Core/Jobs/JobRepository.cs b/src/NzbDrone.Core/Jobs/JobRepository.cs index 8e2aa5858..b09e598b4 100644 --- a/src/NzbDrone.Core/Jobs/JobRepository.cs +++ b/src/NzbDrone.Core/Jobs/JobRepository.cs @@ -23,7 +23,7 @@ namespace NzbDrone.Core.Jobs public ScheduledTask GetDefinition(Type type) { - return Query.Single(c => c.TypeName == type.FullName); + return Query.Where(c => c.TypeName == type.FullName).Single(); } public void SetLastExecutionTime(int id, DateTime executionTime) diff --git a/src/NzbDrone.Core/Metadata/Files/MetadataFileRepository.cs b/src/NzbDrone.Core/Metadata/Files/MetadataFileRepository.cs index 38889fbb3..64f7b871e 100644 --- a/src/NzbDrone.Core/Metadata/Files/MetadataFileRepository.cs +++ b/src/NzbDrone.Core/Metadata/Files/MetadataFileRepository.cs @@ -56,7 +56,7 @@ namespace NzbDrone.Core.Metadata.Files public MetadataFile FindByPath(string path) { - return Query.SingleOrDefault(c => c.RelativePath == path); + return Query.Where(c => c.RelativePath == path).SingleOrDefault(); } } } diff --git a/src/NzbDrone.Core/Qualities/QualityDefinitionRepository.cs b/src/NzbDrone.Core/Qualities/QualityDefinitionRepository.cs index f73fb2de8..0b669f331 100644 --- a/src/NzbDrone.Core/Qualities/QualityDefinitionRepository.cs +++ b/src/NzbDrone.Core/Qualities/QualityDefinitionRepository.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Core.Qualities { try { - return Query.Single(q => (int)q.Quality == qualityId); + return Query.Where(q => (int) q.Quality == qualityId).Single(); } catch (InvalidOperationException e) { diff --git a/src/NzbDrone.Core/Tv/EpisodeRepository.cs b/src/NzbDrone.Core/Tv/EpisodeRepository.cs index 58099d8c3..dcbe99e1e 100644 --- a/src/NzbDrone.Core/Tv/EpisodeRepository.cs +++ b/src/NzbDrone.Core/Tv/EpisodeRepository.cs @@ -37,22 +37,31 @@ namespace NzbDrone.Core.Tv public Episode Find(int seriesId, int season, int episodeNumber) { - return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SeasonNumber == season && s.EpisodeNumber == episodeNumber); + return Query.Where(s => s.SeriesId == seriesId) + .AndWhere(s => s.SeasonNumber == season) + .AndWhere(s => s.EpisodeNumber == episodeNumber) + .SingleOrDefault(); } public Episode Find(int seriesId, int absoluteEpisodeNumber) { - return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.AbsoluteEpisodeNumber == absoluteEpisodeNumber); + return Query.Where(s => s.SeriesId == seriesId) + .AndWhere(s => s.AbsoluteEpisodeNumber == absoluteEpisodeNumber) + .SingleOrDefault(); } public Episode Get(int seriesId, String date) { - return Query.Single(s => s.SeriesId == seriesId && s.AirDate == date); + return Query.Where(s => s.SeriesId == seriesId) + .AndWhere(s => s.AirDate == date) + .Single(); } public Episode Find(int seriesId, String date) { - return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.AirDate == date); + return Query.Where(s => s.SeriesId == seriesId) + .AndWhere(s => s.AirDate == date) + .SingleOrDefault(); } public List GetEpisodes(int seriesId) @@ -62,7 +71,9 @@ namespace NzbDrone.Core.Tv public List GetEpisodes(int seriesId, int seasonNumber) { - return Query.Where(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber).ToList(); + return Query.Where(s => s.SeriesId == seriesId) + .AndWhere(s => s.SeasonNumber == seasonNumber) + .ToList(); } public List GetEpisodeByFileId(int fileId) @@ -88,10 +99,12 @@ namespace NzbDrone.Core.Tv public Episode FindEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber) { - return Query.SingleOrDefault(s => s.SeriesId == seriesId && s.SceneSeasonNumber == seasonNumber && s.SceneEpisodeNumber == episodeNumber); + return Query.Where(s => s.SeriesId == seriesId) + .AndWhere(s => s.SceneSeasonNumber == seasonNumber) + .AndWhere(s => s.SceneEpisodeNumber == episodeNumber) + .SingleOrDefault(); } - public List EpisodesBetweenDates(DateTime startDate, DateTime endDate) { return Query.Join(JoinType.Inner, e => e.Series, (e, s) => e.SeriesId == s.Id) diff --git a/src/NzbDrone.Core/Tv/EpisodeService.cs b/src/NzbDrone.Core/Tv/EpisodeService.cs index 5d8064ec5..df27033a9 100644 --- a/src/NzbDrone.Core/Tv/EpisodeService.cs +++ b/src/NzbDrone.Core/Tv/EpisodeService.cs @@ -103,7 +103,6 @@ namespace NzbDrone.Core.Tv }); } - public PagingSpec EpisodesWithoutFiles(PagingSpec pagingSpec) { var episodeResult = _episodeRepository.EpisodesWithoutFiles(pagingSpec, false); @@ -139,7 +138,6 @@ namespace NzbDrone.Core.Tv var episode = GetEpisode(episodeId); var seasonEpisodes = GetEpisodesBySeason(episode.SeriesId, episode.SeasonNumber); - //Ensure that this is either the first episode //or is the last episode in a season that has 10 or more episodes if (seasonEpisodes.First().EpisodeNumber == episode.EpisodeNumber || (seasonEpisodes.Count() >= 10 && seasonEpisodes.Last().EpisodeNumber == episode.EpisodeNumber)) diff --git a/src/NzbDrone.Core/Tv/SeriesRepository.cs b/src/NzbDrone.Core/Tv/SeriesRepository.cs index dbdc1c191..1819ac081 100644 --- a/src/NzbDrone.Core/Tv/SeriesRepository.cs +++ b/src/NzbDrone.Core/Tv/SeriesRepository.cs @@ -25,28 +25,34 @@ namespace NzbDrone.Core.Tv public bool SeriesPathExists(string path) { - return Query.Any(c => c.Path == path); + return Query.Where(c => c.Path == path).Any(); } public Series FindByTitle(string cleanTitle) { - return Query.SingleOrDefault(s => s.CleanTitle.Equals(cleanTitle, StringComparison.InvariantCultureIgnoreCase)); + cleanTitle = cleanTitle.ToLowerInvariant(); + + return Query.Where(s => s.CleanTitle == cleanTitle) + .SingleOrDefault(); } public Series FindByTitle(string cleanTitle, int year) { - return Query.SingleOrDefault(s => s.CleanTitle.Equals(cleanTitle, StringComparison.InvariantCultureIgnoreCase) && - s.Year == year); + cleanTitle = cleanTitle.ToLowerInvariant(); + + return Query.Where(s => s.CleanTitle == cleanTitle) + .AndWhere(s => s.Year == year) + .SingleOrDefault(); } public Series FindByTvdbId(int tvdbId) { - return Query.SingleOrDefault(s => s.TvdbId.Equals(tvdbId)); + return Query.Where(s => s.TvdbId == tvdbId).SingleOrDefault(); } public Series FindByTvRageId(int tvRageId) { - return Query.SingleOrDefault(s => s.TvRageId.Equals(tvRageId)); + return Query.Where(s => s.TvRageId == tvRageId).SingleOrDefault(); } public void SetSeriesType(int seriesId, SeriesTypes seriesType) diff --git a/src/NzbDrone.Core/Tv/SeriesService.cs b/src/NzbDrone.Core/Tv/SeriesService.cs index 2dcd44283..eeaa24054 100644 --- a/src/NzbDrone.Core/Tv/SeriesService.cs +++ b/src/NzbDrone.Core/Tv/SeriesService.cs @@ -98,8 +98,6 @@ namespace NzbDrone.Core.Tv return FindByTvdbId(tvdbId.Value); } - var clean = Parser.Parser.CleanSeriesTitle(title); - return _seriesRepository.FindByTitle(Parser.Parser.CleanSeriesTitle(title)); }