diff --git a/Greenshot/Helpers/ImageOutput.cs b/Greenshot/Helpers/ImageOutput.cs index e02d2f54c..9522c37c4 100644 --- a/Greenshot/Helpers/ImageOutput.cs +++ b/Greenshot/Helpers/ImageOutput.cs @@ -40,7 +40,7 @@ namespace Greenshot.Helpers { private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageOutput)); private static CoreConfiguration conf = IniConfig.GetIniSection(); private static readonly int PROPERTY_TAG_SOFTWARE_USED = 0x0131; - private static CacheHelper tmpFileCache = new CacheHelper("tmpfile", 60*60*10, new CacheObjectExpired(RemoveExpiredTmpFile)); + private static Cache tmpFileCache = new Cache(10*60*60, new Cache.CacheObjectExpired(RemoveExpiredTmpFile)); /// /// Creates a PropertyItem (Metadata) to store with the image. @@ -314,11 +314,12 @@ namespace Greenshot.Helpers { /// Cleanup all created tmpfiles /// public static void RemoveTmpFiles() { - foreach(string tmpFile in tmpFileCache.GetElements()) { + foreach(string tmpFile in tmpFileCache.Elements) { if (File.Exists(tmpFile)) { LOG.DebugFormat("Removing old temp file {0}", tmpFile); File.Delete(tmpFile); } + tmpFileCache.Remove(tmpFile); } } diff --git a/GreenshotConfluencePlugin/Confluence.cs b/GreenshotConfluencePlugin/Confluence.cs index 94c9bee19..a8d69d96b 100644 --- a/GreenshotConfluencePlugin/Confluence.cs +++ b/GreenshotConfluencePlugin/Confluence.cs @@ -102,7 +102,7 @@ namespace Confluence { private ConfluenceSoapServiceService confluence; private int timeout; private string url; - private CacheHelper pageCache = new CacheHelper("confluencepage", 60*config.Timeout); + private Cache pageCache = new Cache(60 * config.Timeout); public ConfluenceConnector(string url, int timeout) { this.url = url; @@ -210,8 +210,8 @@ namespace Confluence { public Page getPage(string spaceKey, string pageTitle) { RemotePage page = null; string cacheKey = spaceKey + pageTitle; - if (pageCache.Exists(cacheKey)) { - page = pageCache.Get(cacheKey); + if (pageCache.Contains(cacheKey)) { + page = pageCache[cacheKey]; } if (page == null) { checkCredentials(); @@ -225,8 +225,8 @@ namespace Confluence { RemotePage page = null; string cacheKey = "" + pageId; - if (pageCache.Exists(cacheKey)) { - page = pageCache.Get(cacheKey); + if (pageCache.Contains(cacheKey)) { + page = pageCache[cacheKey]; } if (page == null) { checkCredentials(); diff --git a/GreenshotJiraPlugin/Jira.cs b/GreenshotJiraPlugin/Jira.cs index ac536442a..3dfd35ac9 100644 --- a/GreenshotJiraPlugin/Jira.cs +++ b/GreenshotJiraPlugin/Jira.cs @@ -108,8 +108,8 @@ namespace Jira { private JiraSoapServiceService jira; private int timeout; private string url; - private CacheHelper jiraCache = new CacheHelper("jiraissue", 60*config.Timeout); - private CacheHelper userCache = new CacheHelper("jirauser", 60*config.Timeout); + private Cache jiraCache = new Cache(60 * config.Timeout); + private Cache userCache = new Cache(60 * config.Timeout); public JiraConnector() : this(false) { } @@ -246,8 +246,8 @@ namespace Jira { public JiraIssue getIssue(string key) { JiraIssue jiraIssue = null; - if (jiraCache.Exists(key)) { - jiraIssue = jiraCache.Get(key); + if (jiraCache.Contains(key)) { + jiraIssue = jiraCache[key]; } if (jiraIssue == null) { checkCredentials(); @@ -331,8 +331,8 @@ namespace Jira { private string getUserFullName(string user) { string fullname = null; if (user != null) { - if (userCache.Exists(user)) { - fullname = userCache.Get(user).fullname; + if (userCache.Contains(user)) { + fullname = userCache[user].fullname; } else { checkCredentials(); RemoteUser remoteUser = jira.getUser(credentials, user); diff --git a/GreenshotPlugin/Core/Cache.cs b/GreenshotPlugin/Core/Cache.cs new file mode 100644 index 000000000..cfa4de59b --- /dev/null +++ b/GreenshotPlugin/Core/Cache.cs @@ -0,0 +1,196 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: http://getgreenshot.org/ + * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +using System; +using System.Collections.Generic; +using System.Timers; + +namespace GreenshotPlugin.Core { + /// + /// Cache class + /// + /// Type of key + /// Type of value + public class Cache { + private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger("Cache"); + private IDictionary internalCache = new Dictionary(); + private object lockObject = new object(); + private int secondsToExpire = 10; + private CacheObjectExpired expiredCallback = null; + public delegate void CacheObjectExpired(TK key, TV cacheValue); + + /// + /// Initialize the cache + /// + public Cache() { + } + /// + /// Initialize the cache + /// + /// + public Cache(CacheObjectExpired expiredCallback) : this() { + this.expiredCallback = expiredCallback; + } + + /// + /// Initialize the cache with a expire setting + /// + /// + public Cache(int secondsToExpire) : this() { + this.secondsToExpire = secondsToExpire; + } + + /// + /// Initialize the cache with a expire setting + /// + /// + /// + public Cache(int secondsToExpire, CacheObjectExpired expiredCallback) : this(expiredCallback) { + this.secondsToExpire = secondsToExpire; + } + + /// + /// Enumerable for the values in the cache + /// + public IEnumerable Elements { + get { + List elements = new List(); + + foreach (TV element in internalCache.Values) { + elements.Add(element); + } + foreach (TV element in elements) { + yield return element; + } + } + } + + /// + /// Get the value by key from the cache + /// + /// + /// + public TV this[TK key] { + get { + TV result = default(TV); + lock (lockObject) { + if (internalCache.ContainsKey(key)) { + result = internalCache[key]; + } + } + return result; + } + } + + /// + /// Contains + /// + /// + /// true if the cache contains the key + public bool Contains(TK key) { + return internalCache.ContainsKey(key); + } + + /// + /// Add a value to the cache + /// + /// + /// + public void Add(TK key, TV value) { + lock (lockObject) { + var cachedItem = new CachedItem(key, value, secondsToExpire); + cachedItem.Expired += delegate(TK cacheKey, TV cacheValue) { + if (internalCache.ContainsKey(cacheKey)) { + LOG.DebugFormat("Expiring object with Key: {0}", cacheKey); + if (expiredCallback != null) { + expiredCallback(cacheKey, cacheValue); + } + Remove(cacheKey); + } else { + LOG.DebugFormat("Expired old object with Key: {0}", cacheKey); + } + }; + + if (internalCache.ContainsKey(key)) { + internalCache[key] = value; + LOG.DebugFormat("Updated item with Key: {0}", key); + } else { + internalCache.Add(key, cachedItem); + LOG.DebugFormat("Added item with Key: {0}", key); + } + } + } + + /// + /// Remove item from cache + /// + /// + public void Remove(TK key) { + lock (lockObject) { + if (!internalCache.ContainsKey(key)) { + throw new ApplicationException(String.Format("An object with key ‘{0}’ does not exists in cache", key)); + } + internalCache.Remove(key); + LOG.DebugFormat("Removed item with Key: {0}", key); + } + } + + /// + /// A cache item + /// + private class CachedItem { + public event CacheObjectExpired Expired; + private int secondsToExpire; + private readonly Timer _timerEvent; + + public CachedItem(TK key, TV item, int secondsToExpire) { + if (key == null) { + throw new ArgumentNullException("key is not valid"); + } + Key = key; + Item = item; + this.secondsToExpire = secondsToExpire; + if (secondsToExpire > 0) { + _timerEvent = new Timer(secondsToExpire * 1000) { AutoReset = false }; + _timerEvent.Elapsed += timerEvent_Elapsed; + _timerEvent.Start(); + } + } + + private void ExpireNow() { + _timerEvent.Stop(); + if (secondsToExpire > 0 && Expired != null) { + Expired(Key, Item); + } + } + + private void timerEvent_Elapsed(object sender, ElapsedEventArgs e) { + ExpireNow(); + } + + public TK Key { get; private set; } + public TV Item { get; private set; } + + public static implicit operator TV(CachedItem a) { + return a.Item; + } + } + } +} \ No newline at end of file diff --git a/GreenshotPlugin/Core/CacheHelper.cs b/GreenshotPlugin/Core/CacheHelper.cs deleted file mode 100644 index e3496aea1..000000000 --- a/GreenshotPlugin/Core/CacheHelper.cs +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Greenshot - a free and open source screenshot tool - * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom - * - * For more information see: http://getgreenshot.org/ - * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Web; -using System.Web.Caching; - -namespace GreenshotPlugin.Core { - public delegate void CacheObjectExpired(string key, object cacheValue); - - /// - /// Description of CacheHelper. - /// - public class CacheHelper { - private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger("CacheHelper"); - private Cache cache = HttpRuntime.Cache; - private string prefix; - private double defaultExpiration = 10*60; // 10 Minutes - private CacheItemRemovedCallback defaultCallback = null; - private CacheObjectExpired expiredCallback = null; - - public CacheHelper(string prefix) { - defaultCallback = new CacheItemRemovedCallback(OnRemoved); - this.prefix = prefix + "."; - } - - public CacheHelper(string prefix, double defaultExpiration) : this(prefix) { - this.defaultExpiration = defaultExpiration; - } - - public CacheHelper(string prefix, double defaultExpiration, CacheObjectExpired expiredCallback) : this(prefix, defaultExpiration) { - this.expiredCallback = expiredCallback; - } - - private void OnRemoved(string key, object cacheValue, CacheItemRemovedReason reason) { - LOG.DebugFormat("The item with key '{0}' is being removed from the cache with reason: {1}", key, reason); - switch (reason) { - case CacheItemRemovedReason.Expired: - if (expiredCallback != null) { - expiredCallback.Invoke(key, cacheValue); - } - break; - case CacheItemRemovedReason.Underused: - break; - } - } - - /// - /// Insert value into the cache using default expiration & default callback - /// - /// Item to be cached - /// Name of item - public void Add(string key, T o) { - if (defaultCallback != null) { - cache.Insert(prefix + key, o, null, DateTime.Now.AddSeconds(defaultExpiration), Cache.NoSlidingExpiration, CacheItemPriority.Default, defaultCallback); - } else { - cache.Insert(prefix + key, o, null, DateTime.Now.AddSeconds(defaultExpiration), Cache.NoSlidingExpiration); - - } - } - - /// - /// Get all the methods for this cache - /// - /// IEnumerator of the type - public IEnumerable GetElements() { - IDictionaryEnumerator cacheEnum = cache.GetEnumerator(); - while (cacheEnum.MoveNext()) { - string key = cacheEnum.Key as string; - if (!string.IsNullOrEmpty(key) && key.StartsWith(prefix)) { - yield return (T)cacheEnum.Value; - } - } - } - - /// - /// Insert value into the cache using the supplied expiration time in seconds - /// - /// Item to be cached - /// Name of item - /// expiration time in "double" seconds - public void Add(string key, T o, double seconds) { - cache.Insert(prefix + key, o, null, DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration); - } - - /// - /// Insert value into the cache using - /// appropriate name/value pairs - /// - /// Item to be cached - /// Name of item - public void Add(string key, T o, CacheItemRemovedCallback callback) { - cache.Insert(prefix + key, o, null, DateTime.Now.AddSeconds(defaultExpiration), Cache.NoSlidingExpiration, CacheItemPriority.Default, callback); - } - - /// - /// Remove item from cache - /// - /// Name of cached item - public void Remove(string key) { - cache.Remove(prefix + key); - } - - /// - /// Check for item in cache - /// - /// Name of cached item - /// - public bool Exists(string key) { - return cache[prefix + key] != null; - } - - /// - /// Retrieve cached item - /// - /// Name of cached item - /// Cached item as type - public T Get(string key) { - try { - return (T) cache[prefix + key]; - } catch { - return default(T); - } - } - } -} diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj index 2ceb34fd1..dbe8a9707 100644 --- a/GreenshotPlugin/GreenshotPlugin.csproj +++ b/GreenshotPlugin/GreenshotPlugin.csproj @@ -50,7 +50,6 @@ - @@ -218,7 +217,7 @@ - +