private static CacheStore GetCacheStore( UniqingScope uniqingScope, string scopeDelimiter, CacheContentType contentType ) { // make sure we always get the global cache if scope is global if( scope == UniqingScope.Application ) { scopeDelimiter = null; } else if( scopeDelimiter == null ) { scopeDelimiter = GetScopeDelimiter(); } // determine which cache to use - first get array of cache stores for the specified scope string scopeKey = String.Format( "{0}|{1}", uniqingScope, scopeDelimiter ); CacheStore[] cacheStores = stores[ scopeKey ] as CacheStore[]; if( cacheStores == null ) { cacheStores = new CacheStore[Enum.GetNames( typeof(CacheContentType) ).Length]; stores[ scopeKey ] = cacheStores; } // get specific cache store by content type CacheStore cacheStore = cacheStores[ (int) contentType ]; if( cacheStore == null ) { cacheStore = new CacheStore(); cacheStores[ (int) contentType ] = cacheStore; } return cacheStore; }
private static CacheStore GetCacheStore(UniqingScope uniqingScope, string scopeDelimiter, CacheContentType contentType) { // make sure we always get the global cache if scope is global if (scope == UniqingScope.Application) { scopeDelimiter = null; } else if (scopeDelimiter == null) { scopeDelimiter = GetScopeDelimiter(); } // determine which cache to use - first get array of cache stores for the specified scope string scopeKey = String.Format("{0}|{1}", uniqingScope, scopeDelimiter); CacheStore[] cacheStores = stores[scopeKey] as CacheStore[]; if (cacheStores == null) { cacheStores = new CacheStore[Enum.GetNames(typeof(CacheContentType)).Length]; stores[scopeKey] = cacheStores; } // get specific cache store by content type CacheStore cacheStore = cacheStores[(int)contentType]; if (cacheStore == null) { cacheStore = new CacheStore(); cacheStores[(int)contentType] = cacheStore; } return(cacheStore); }
/// <summary> /// Forcefully remove one or more entries from the cache. Note that this /// is currently a O(n^2) operation (i.e. it might be slow). /// </summary> /// <param name="objects">The objects to remove from the cache.</param> public static void Remove(params object[] objects) { Check.VerifyNotNull(objects, Error.NullParameter, "objects"); // determine which cache to use CacheStore cacheStore = GetCacheStore(CacheContentType.Entity); // access cache cacheStore.Lock.AcquireWriterLock(rwLockTimeOut); try { if (objects != null && objects.Length > 0) { foreach (object obj in objects) { if (obj is ICacheKeyProvider) { ICacheKeyProvider ckp = obj as ICacheKeyProvider; cacheStore.Remove(ckp.CacheKey); } else { cacheStore.RemoveObject(obj); } } } } finally { cacheStore.Lock.ReleaseWriterLock(); } }
/// <summary> /// Retrieve an entry from the cache using the specified key. /// </summary> /// <param name="key">The key linked to the cache entry.</param> /// <returns>The cached object (or null if no entry was found).</returns> public static object Get(string key) { Check.VerifyNotNull(key, Error.NullParameter, "key"); object result = null; // determine which cache to use CacheContentType contentType = key.StartsWith("Query|") ? CacheContentType.Query : CacheContentType.Entity; CacheStore cacheStore = GetCacheStore(contentType); // access cache cacheStore.Lock.AcquireReaderLock(rwLockTimeOut); try { result = cacheStore.Get(key); } finally { cacheStore.Lock.ReleaseReaderLock(); } // logging Check.LogDebug(LogCategories.Cache, "Cache (get) using key: {0} ({1})", key, result != null ? "hit" : "miss"); // statistics if (result != null) { GentleStatistics.CacheHits += 1; } else { GentleStatistics.CacheMisses += 1; } return(result); }
/// <summary> /// Return the number of items currently in the cache. The cache store to use is determined from /// the scope parameter (combined with the global UniqingScope setting). If null is passed this /// method returns the same as the Count property (current scope). /// </summary> public static int GetCount(string scopeDelimiter, CacheContentType contentType) { CacheStore cacheStore = GetCacheStore(scope, scopeDelimiter, contentType); // we need a writer lock because computing the count also removes collected entries cacheStore.Lock.AcquireWriterLock(rwLockTimeOut); try { return(cacheStore.Count); } finally { cacheStore.Lock.ReleaseWriterLock(); } }
/// <summary> /// Clear all entries belonging to the specified scope from the cache. /// </summary> public static void Clear(string scopeDelimiter, CacheContentType contentType) { // determine which cache to use CacheStore cacheStore = GetCacheStore(scope, scopeDelimiter, contentType); // access cache cacheStore.Lock.AcquireWriterLock(rwLockTimeOut); try { cacheStore.Clear(); GentleStatistics.Reset(LogCategories.Cache); } finally { cacheStore.Lock.ReleaseWriterLock(); } }
/// <summary> /// Remove an entry from the cache. /// </summary> /// <param name="key">The key used to find the entry to remove.</param> public static void Remove(string key) { Check.VerifyNotNull(key, Error.NullParameter, "key"); // determine which cache to use CacheStore cacheStore = GetCacheStore(CacheContentType.Entity); // access cache cacheStore.Lock.AcquireWriterLock(rwLockTimeOut); try { cacheStore.Remove(key); } finally { cacheStore.Lock.ReleaseWriterLock(); } }
/// <summary> /// Insert an entry into the cache using the specified <see cref="CacheStrategy"/>. /// </summary> /// <param name="key">The key used to find the entry again.</param> /// <param name="value">The item to cache.</param> /// <param name="strategy">The cache strategy to use for lifetime management. Possible /// values are Never, Temporary or Permanent.</param> public static void Insert(string key, object value, CacheStrategy strategy) { Check.VerifyNotNull(key, Error.NullParameter, "key"); Check.VerifyNotNull(value, Error.NullParameter, "value"); Check.LogDebug(LogCategories.Cache, "Cache (add) using key: " + key); CacheContentType contentType = key.StartsWith("Query|") ? CacheContentType.Query : CacheContentType.Entity; // determine which cache to use CacheStore cacheStore = GetCacheStore(contentType); // access cache cacheStore.Lock.AcquireWriterLock(rwLockTimeOut); try { cacheStore.Insert(key, value, strategy); } finally { cacheStore.Lock.ReleaseWriterLock(); } }
private static CacheStore[] GetCacheStores(UniqingScope uniqingScope, string scopeDelimiter) { // make sure we always get the global cache if scope is global if (scope == UniqingScope.Application) { scopeDelimiter = null; } else if (scopeDelimiter == null) { scopeDelimiter = GetScopeDelimiter(); } // determine which cache to use string scopeKey = String.Format("{0}|{1}", uniqingScope, scopeDelimiter); CacheStore[] cacheStores = stores[scopeKey] as CacheStore[]; if (cacheStores == null) { cacheStores = new CacheStore[Enum.GetNames(typeof(CacheContentType)).Length]; stores[scopeKey] = cacheStores; } return(cacheStores); }
/// <summary> /// Clear information on query results for select/count queries on the specified type. /// This method is used by Gentle to invalidate obsolete query results when objects /// of the given type are inserted or removed. /// </summary> public static void ClearQueryResultsByType(Type type) { // this is a bit hackish but does the job for now string match = String.Format("{0}|{1}|select ", CacheContentType.Query, type); // process all cache stores and remove query results if invalidated foreach (CacheStore[] cacheStores in stores.Values) { CacheStore cacheStore = cacheStores[(int)CacheContentType.Query]; if (cacheStore != null) { IList removeList = new ArrayList(); cacheStore.Lock.AcquireWriterLock(rwLockTimeOut); try { // build list of items to remove foreach (CacheEntry entry in cacheStore) { if (entry.Key.Length >= match.Length && entry.Key.Substring(0, match.Length).Equals(match)) { removeList.Add(entry.Key); } } // remove found items foreach (string key in removeList) { cacheStore.Remove(key); } } finally { cacheStore.Lock.ReleaseWriterLock(); } } } }
private static CacheStore[] GetCacheStores( UniqingScope uniqingScope, string scopeDelimiter ) { // make sure we always get the global cache if scope is global if( scope == UniqingScope.Application ) { scopeDelimiter = null; } else if( scopeDelimiter == null ) { scopeDelimiter = GetScopeDelimiter(); } // determine which cache to use string scopeKey = String.Format( "{0}|{1}", uniqingScope, scopeDelimiter ); CacheStore[] cacheStores = stores[ scopeKey ] as CacheStore[]; if( cacheStores == null ) { cacheStores = new CacheStore[Enum.GetNames( typeof(CacheContentType) ).Length]; stores[ scopeKey ] = cacheStores; } return cacheStores; }