diff --git a/NzbDrone.Common.Test/CacheTests/CachedFixture.cs b/NzbDrone.Common.Test/CacheTests/CachedFixture.cs index 08125abc0..68f6d54ef 100644 --- a/NzbDrone.Common.Test/CacheTests/CachedFixture.cs +++ b/NzbDrone.Common.Test/CacheTests/CachedFixture.cs @@ -75,6 +75,24 @@ namespace NzbDrone.Common.Test.CacheTests _cachedString.Get("Key").Should().Be("New"); } + + [Test] + public void should_store_null() + { + int hitCount = 0; + + + for (int i = 0; i < 10; i++) + { + _cachedString.Get("key", () => + { + hitCount++; + return null; + }); + } + + hitCount.Should().Be(1); + } } public class Worker diff --git a/NzbDrone.Common/Cache/CacheManger.cs b/NzbDrone.Common/Cache/CacheManger.cs index 98d5846d0..b5ab02844 100644 --- a/NzbDrone.Common/Cache/CacheManger.cs +++ b/NzbDrone.Common/Cache/CacheManger.cs @@ -5,8 +5,8 @@ namespace NzbDrone.Common.Cache { public interface ICacheManger { - ICached GetCache(Type type); - ICached GetCache(object host); + ICached GetCache(Type host, string name); + ICached GetCache(Type host); } public class CacheManger : ICacheManger @@ -19,16 +19,18 @@ namespace NzbDrone.Common.Cache } - public ICached GetCache(Type type) + public ICached GetCache(Type host) { - Ensure.That(() => type).IsNotNull(); - - return (ICached)_cache.Get(type.FullName, () => new Cached()); + Ensure.That(() => host).IsNotNull(); + return GetCache(host, host.FullName); } - public ICached GetCache(object host) + public ICached GetCache(Type host, string name) { - return GetCache(host.GetType()); + Ensure.That(() => host).IsNotNull(); + Ensure.That(() => name).IsNotNullOrWhiteSpace(); + + return (ICached)_cache.Get(host.FullName + "_" + name, () => new Cached()); } } } \ No newline at end of file diff --git a/NzbDrone.Common/Cache/Cached.cs b/NzbDrone.Common/Cache/Cached.cs index e3ff83210..59ac622c7 100644 --- a/NzbDrone.Common/Cache/Cached.cs +++ b/NzbDrone.Common/Cache/Cached.cs @@ -25,6 +25,13 @@ namespace NzbDrone.Common.Cache return Get(key, () => { throw new KeyNotFoundException(key); }); } + public T Find(string key) + { + T value; + _store.TryGetValue(key, out value); + return value; + } + public T Get(string key, Func function) { Ensure.That(() => key).IsNotNullOrWhiteSpace(); diff --git a/NzbDrone.Common/Cache/ICached.cs b/NzbDrone.Common/Cache/ICached.cs index bc79856b8..cd4fc9e28 100644 --- a/NzbDrone.Common/Cache/ICached.cs +++ b/NzbDrone.Common/Cache/ICached.cs @@ -10,5 +10,6 @@ namespace NzbDrone.Common.Cache void Clear(); void Remove(string key); T Get(string key); + T Find(string key); } } \ No newline at end of file diff --git a/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/NzbDrone.Core/Configuration/ConfigFileProvider.cs index 882e7e5e6..99d6ec882 100644 --- a/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -32,7 +32,7 @@ namespace NzbDrone.Core.Configuration public ConfigFileProvider(IEnvironmentProvider environmentProvider, ICacheManger cacheManger) { _environmentProvider = environmentProvider; - _cache = cacheManger.GetCache(this); + _cache = cacheManger.GetCache(this.GetType()); _configFile = _environmentProvider.GetConfigPath(); } diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs index 1e3aaec37..b5c7fcdd9 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingRepository.cs @@ -6,8 +6,6 @@ namespace NzbDrone.Core.DataAugmentation.Scene { public interface ISceneMappingRepository : IBasicRepository { - SceneMapping FindByTvdbId(int tvdbId); - SceneMapping FindByCleanTitle(string cleanTitle); } @@ -18,14 +16,5 @@ namespace NzbDrone.Core.DataAugmentation.Scene { } - public SceneMapping FindByTvdbId(int tvdbId) - { - return Query.SingleOrDefault(c => c.TvdbId == tvdbId); - } - - public SceneMapping FindByCleanTitle(string cleanTitle) - { - return Query.SingleOrDefault(c => c.CleanTitle == cleanTitle); - } } } \ No newline at end of file diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs index 2613b7055..406e2d6de 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using NLog; +using NzbDrone.Common.Cache; using NzbDrone.Common.Messaging; using NzbDrone.Core.Lifecycle; @@ -22,33 +23,43 @@ namespace NzbDrone.Core.DataAugmentation.Scene private readonly ISceneMappingRepository _repository; private readonly ISceneMappingProxy _sceneMappingProxy; private readonly Logger _logger; + private readonly ICached _getSceneNameCache; + private readonly ICached _gettvdbIdCache; - public SceneMappingService(ISceneMappingRepository repository, ISceneMappingProxy sceneMappingProxy, Logger logger) + public SceneMappingService(ISceneMappingRepository repository, ISceneMappingProxy sceneMappingProxy, ICacheManger cacheManger, Logger logger) { _repository = repository; _sceneMappingProxy = sceneMappingProxy; + + _getSceneNameCache = cacheManger.GetCache(GetType(), "scene_name"); + _gettvdbIdCache = cacheManger.GetCache(GetType(), "tvdb_id"); _logger = logger; } public string GetSceneName(int tvdbId, int seasonNumber = -1) { - var mapping = _repository.FindByTvdbId(tvdbId); + lock (mutex) + { + var mapping = _getSceneNameCache.Find(tvdbId.ToString()); - if (mapping == null) return null; + if (mapping == null) return null; - return mapping.SceneName; + return mapping.SceneName; + } } - public Nullable GetTvDbId(string cleanName) { - var mapping = _repository.FindByCleanTitle(cleanName); + lock (mutex) + { + var mapping = _gettvdbIdCache.Find(cleanName); - if (mapping == null) - return null; + if (mapping == null) + return null; - return mapping.TvdbId; + return mapping.TvdbId; + } } @@ -65,13 +76,22 @@ namespace NzbDrone.Core.DataAugmentation.Scene try { var mappings = _sceneMappingProxy.Fetch(); - + lock (mutex) { if (mappings.Any()) { _repository.Purge(); _repository.InsertMany(mappings); + + _gettvdbIdCache.Clear(); + _getSceneNameCache.Clear(); + + foreach (var sceneMapping in mappings) + { + _getSceneNameCache.Set(sceneMapping.TvdbId.ToString(), sceneMapping); + _gettvdbIdCache.Set(sceneMapping.CleanTitle, sceneMapping); + } } else { diff --git a/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index a3f7ee688..b39a818b3 100644 --- a/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.Instrumentation { Layout = new SimpleLayout("${callsite:className=false:fileName=false:includeSourcePath=false:methodName=true}"); - Rule = new LoggingRule("*", LogLevel.Trace, this); + Rule = new LoggingRule("*", LogLevel.Debug, this); LogManager.Configuration.AddTarget("DbLogger", this); LogManager.Configuration.LoggingRules.Add(Rule);