Beispiel #1
0
		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();
                    }
                }
            }
        }
Beispiel #11
0
		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;
		}