From 7f6c70d7b24b3c39d5b39cc47e2b48d6a9bac794 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 4 Aug 2016 21:53:19 +0100 Subject: [PATCH] Some small tweaks to improve the memory alloc --- PlexRequests.Helpers/MemoryCacheProvider.cs | 261 +++++++++--------- .../Interfaces/IAvailabilityChecker.cs | 2 +- .../Jobs/PlexAvailabilityChecker.cs | 8 +- .../Jobs/PlexEpisodeCacher.cs | 25 +- PlexRequests.UI/Views/Admin/Plex.cshtml | 1 - 5 files changed, 147 insertions(+), 150 deletions(-) diff --git a/PlexRequests.Helpers/MemoryCacheProvider.cs b/PlexRequests.Helpers/MemoryCacheProvider.cs index c85ef40f0..98b10408c 100644 --- a/PlexRequests.Helpers/MemoryCacheProvider.cs +++ b/PlexRequests.Helpers/MemoryCacheProvider.cs @@ -1,130 +1,133 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: MemoryCacheProvider.cs -// Created By: Jamie Rees -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// ************************************************************************/ -#endregion -using System; -using System.Linq; -using System.Runtime.Caching; -using System.Threading.Tasks; - -namespace PlexRequests.Helpers -{ - public class MemoryCacheProvider : ICacheProvider - { - private ObjectCache Cache => MemoryCache.Default; - - /// - /// Gets the item from the cache, if the item is not present - /// then we will get that item and store it in the cache. - /// - /// Type to store in the cache. - /// The key. - /// The item callback. This will be called if the item is not present in the cache. - /// - /// The amount of time we want to cache the object. - /// A copy of the cached object. - /// If the ]]> itemCallback is null and the item is not in the cache it will throw a . - /// If you do not want to change the object in the cache (since it's a copy returned and not a reference) you will need to - /// the cached item and then it, or just call this method. - public T GetOrSet(string key, Func itemCallback, int cacheTime = 20) where T : class - { - var item = Get(key); - if (item == null) - { - item = itemCallback(); - if (item != null) - { - Set(key, item, cacheTime); - } - } - - // Return a copy, not the stored cache reference - // The cached object will not change - // If we - return item.CloneJson(); - } - - public async Task GetOrSetAsync(string key, Func> itemCallback, int cacheTime = 20) where T : class - { - var item = Get(key); - if (item == null) - { - item = await itemCallback(); - if (item != null) - { - Set(key, item, cacheTime); - } - } - - // Return a copy, not the stored cache reference - // The cached object will not change - return item.CloneJson(); - } - - /// - /// Gets the specified item from the cache. - /// - /// Type to get from the cache - /// The key. - /// - public T Get(string key) where T : class - { - lock (key) - return Cache.Get(key) as T; - } - - /// - /// Set/Store the specified object in the cache - /// - /// The key. - /// The object we want to store. - /// The amount of time we want to cache the object. - public void Set(string key, object data, int cacheTime = 20) - { - var policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime) }; - lock (key) - { - Cache.Remove(key); - Cache.Add(new CacheItem(key, data), policy); - } - } - - /// - /// Removes the specified object from the cache. - /// - /// The key. - public void Remove(string key) - { - var keys = Cache.Where(x => x.Key.Contains(key)); - foreach (var k in keys) - { - lock (key) - { - Cache.Remove(k.Key); - } - } - } - } +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: MemoryCacheProvider.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +using System; +using System.Linq; +using System.Runtime.Caching; +using System.Threading.Tasks; + +namespace PlexRequests.Helpers +{ + public class MemoryCacheProvider : ICacheProvider + { + private ObjectCache Cache => MemoryCache.Default; + private readonly object _lock = new object(); + + /// + /// Gets the item from the cache, if the item is not present + /// then we will get that item and store it in the cache. + /// + /// Type to store in the cache. + /// The key. + /// The item callback. This will be called if the item is not present in the cache. + /// + /// The amount of time we want to cache the object. + /// A copy of the cached object. + /// If the ]]> itemCallback is null and the item is not in the cache it will throw a . + /// If you do not want to change the object in the cache (since it's a copy returned and not a reference) you will need to + /// the cached item and then it, or just call this method. + public T GetOrSet(string key, Func itemCallback, int cacheTime = 20) where T : class + { + var item = Get(key); + if (item == null) + { + item = itemCallback(); + if (item != null) + { + Set(key, item, cacheTime); + } + } + + // Return a copy, not the stored cache reference + // The cached object will not change + // If we + return item.CloneJson(); + } + + public async Task GetOrSetAsync(string key, Func> itemCallback, int cacheTime = 20) where T : class + { + var item = Get(key); + if (item == null) + { + item = await itemCallback(); + if (item != null) + { + Set(key, item, cacheTime); + } + } + + // Return a copy, not the stored cache reference + // The cached object will not change + return item.CloneJson(); + } + + /// + /// Gets the specified item from the cache. + /// + /// Type to get from the cache + /// The key. + /// + public T Get(string key) where T : class + { + lock (_lock) + { + return Cache.Get(key) as T; + } + } + + /// + /// Set/Store the specified object in the cache + /// + /// The key. + /// The object we want to store. + /// The amount of time we want to cache the object. + public void Set(string key, object data, int cacheTime = 20) + { + var policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime) }; + lock (_lock) + { + Cache.Remove(key); + Cache.Add(new CacheItem(key, data), policy); + } + } + + /// + /// Removes the specified object from the cache. + /// + /// The key. + public void Remove(string key) + { + var keys = Cache.Where(x => x.Key.Contains(key)); + foreach (var k in keys) + { + lock (_lock) + { + Cache.Remove(k.Key); + } + } + } + } } \ No newline at end of file diff --git a/PlexRequests.Services/Interfaces/IAvailabilityChecker.cs b/PlexRequests.Services/Interfaces/IAvailabilityChecker.cs index 96411cb15..fd0434e00 100644 --- a/PlexRequests.Services/Interfaces/IAvailabilityChecker.cs +++ b/PlexRequests.Services/Interfaces/IAvailabilityChecker.cs @@ -43,7 +43,7 @@ namespace PlexRequests.Services.Interfaces /// Gets the episode's stored in the cache. /// /// - IEnumerable GetEpisodeCache(); + HashSet GetEpisodeCache(); /// /// Gets the episode's stored in the cache and then filters on the TheTvDBId. /// diff --git a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs index a0df532c7..569babb4e 100644 --- a/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs +++ b/PlexRequests.Services/Jobs/PlexAvailabilityChecker.cs @@ -241,7 +241,7 @@ namespace PlexRequests.Services.Jobs public bool IsEpisodeAvailable(string theTvDbId, int season, int episode) { - var episodes = Cache.Get>(CacheKeys.PlexEpisodes); + var episodes = Cache.Get>(CacheKeys.PlexEpisodes); if (episodes == null) { Log.Info("Episode cache info is not available. tvdbid: {0}, season: {1}, episode: {2}",theTvDbId, season, episode); @@ -261,13 +261,13 @@ namespace PlexRequests.Services.Jobs /// Gets the episode's stored in the cache. /// /// - public IEnumerable GetEpisodeCache() + public HashSet GetEpisodeCache() { - var episodes = Cache.Get>(CacheKeys.PlexEpisodes); + var episodes = Cache.Get>(CacheKeys.PlexEpisodes); if (episodes == null) { Log.Info("Episode cache info is not available."); - return new List(); + return new HashSet(); } return episodes; } diff --git a/PlexRequests.Services/Jobs/PlexEpisodeCacher.cs b/PlexRequests.Services/Jobs/PlexEpisodeCacher.cs index 9164fd4a8..d50ad0c61 100644 --- a/PlexRequests.Services/Jobs/PlexEpisodeCacher.cs +++ b/PlexRequests.Services/Jobs/PlexEpisodeCacher.cs @@ -65,6 +65,7 @@ namespace PlexRequests.Services.Jobs public void CacheEpisodes() { var results = new PlexSearch(); + var videoHashset = new HashSet