コード例 #1
0
        public void CacheHistoryWorking()
        {
            var       rand         = new Random();
            const int max          = 200; // our cache size covers 20% of our key space
            const int refetches    = 5;
            var       innerFactory = new CacheFactory()
            {
                CacheName = "inner"
            };

            var fac0 = new StochasticCacheFactory()
            {
                MaxSize = max, NumHistoryFetches = 0, Inner = innerFactory
            };
            var fac5 = new StochasticCacheFactory()
            {
                MaxSize = max, NumHistoryFetches = refetches, Inner = innerFactory
            };
            var lruFac = new LruCacheFactory()
            {
                MaxSize = max, Inner = innerFactory
            };

            var cache0 = fac0.Create <int, int>("StochasticCacheTest");
            var cache5 = fac5.Create <int, int>("StochasticCacheTest");
            var lru    = lruFac.Create <int, int>("StochasticCacheTest");

            var cache0Count = 0;
            var cache5Count = 0;
            var lruCount    = 0;

            for (int i = 0; i < 100000; i++)
            {
                var index = i % 5 != 0 ? rand.Next(200) : rand.Next(1000);    // 80 % of hits come out of 20% of the key space.

                cache0.GetOrAdd(index, (key) => { cache0Count++; return(index); });
                cache5.GetOrAdd(index, (key) => { cache5Count++; return(index); });
                lru.GetOrAdd(index, (key) => { lruCount++; return(index); });
            }

            Console.WriteLine("Cache misses, smaller is better  0: {0}, {1}: {2}, lru: {3}", cache0Count, refetches, cache5Count, lruCount);
            Assert.That(cache0Count, Is.GreaterThan(cache5Count));  // It is possible but very very unlikley that this will fail.
        }
コード例 #2
0
        /// <summary>
        /// Create cache, according to the configuration of the factory.
        /// </summary>
        /// <typeparam name="TKey">Type of cache key.</typeparam>
        /// <typeparam name="TValue">Type of cache value.</typeparam>
        /// <param name="cacheName">Name of the cache.</param>
        /// <returns>
        /// A cache.
        /// </returns>
        /// <exception cref="System.InvalidOperationException"></exception>
        public ICache <TKey, TValue> Create <TKey, TValue>(string cacheName)
        {
            ICacheFactory fact = null;

            //
            // The first caches encountered will be lowest in the stack
            //
            if (Redis)
            {
                if (ConfigurationSettings.GetCacheConfigurationSection().RedisCacheSettings.Enabled)
                {
                    fact = new RedisCacheFactory {
                        Inner = null, CompressKey = RedisKeyCompression, CompressValue = RedisValueCompression, KeyExpiry = RedisKeyExpiry
                    };
                }
                else
                {
                    Diagnostics.EventLog.Application.WriteWarning("Cache '{0}' requested a Redis layer but was denied due to the SoftwarePlatform.config settings.", cacheName);
                }
            }

            if (Dictionary)
            {
                fact = new DictionaryCacheFactory {
                    Inner = fact
                };
            }

            if (MaxCacheEntries > 0)
            {
                // Attempt to get the maximum value from the configuration settings
                int configMaxCacheSize = GetMaximumCacheSize(cacheName);
                if (configMaxCacheSize > 0)
                {
                    MaxCacheEntries = configMaxCacheSize;
                }

                if (Lru)
                {
                    fact = new LruCacheFactory {
                        Inner = fact, MaxSize = MaxCacheEntries, EvictionFrequency = LruEvictionFrequency
                    };
                }
                else
                {
                    fact = new StochasticCacheFactory {
                        Inner = fact, MaxSize = MaxCacheEntries
                    };
                }
            }
            if (ExpirationInterval != TimeSpan.Zero)
            {
                fact = new TimeoutCacheFactory {
                    Inner = fact, Expiration = ExpirationInterval, EvictionFrequency = TimeoutEvictionFrequency
                };
            }
            if (TransactionAware)
            {
                fact = new TransactionAwareCacheFactory {
                    Inner = fact
                };
            }
            if (Logging)
            {
                fact = new LoggingCacheFactory {
                    Inner = fact, MaxSize = MaxCacheEntries
                };
            }
            if (fact != null && (ThreadSafe && !fact.ThreadSafe))
            {
                fact = new ThreadSafeCacheFactory {
                    Inner = fact
                };
            }
            if (BlockIfPending || DelayedInvalidates)
            {
                fact = new BlockIfPendingCacheFactory {
                    Inner = fact
                };
            }
            if (DelayedInvalidates)
            {
                // Must be below BlockIfPending
                fact = new DelayedInvalidateCacheFactory {
                    Inner = fact, ExpirationInterval = new TimeSpan(0, 1, 0)
                };
            }
            if (MetadataCache)
            {
                fact = new MetadataCacheFactory {
                    Inner = fact
                };
            }
            if (IsolateTenants)
            {
                fact = new PerTenantNonSharingCacheFactory {
                    Inner = fact
                };
            }


            if (Distributed)
            {
                fact = new RedisPubSubCacheFactory <TKey>(fact, IsolateTenants);
            }

            // Final safety check
            if (fact == null || (ThreadSafe && !fact.ThreadSafe))
            {
                throw new InvalidOperationException();
            }
            var cache = fact.Create <TKey, TValue>(cacheName);

            return(cache);
        }