/// <summary> /// Create and initialize an SACache. /// </summary> /// <param name="cacheSize">The number of entries the cache should track. Defaults to 32M entries.</param> /// <param name="linesPerSet">The number of lines per set (set-associative cardinality). Defaults to 4.</param> /// <param name="evictor">Cache-entry eviction routine. Defaults to LRU. A custom routine may be supplied via a /// a class that implements sacache.IEvictor.</param> /// <param name="hashGenerator">Hash generation mechanism for cache keys. Defaults to Object.GetHashCode().</param> public SACache(uint cacheSize, uint linesPerSet, IEvictor <TKey, TVal> evictor, IHashGenerator <TKey> hashGenerator) { // This is the default, but I like to be explicit in constructors. It helps to know they weren't forgotten... clearStats(); this.cacheSize = cacheSize; if (this.cacheSize < 1) { Debug.WriteLine("[SACache] No cache size specified, using 32M."); this.cacheSize = 32 * 1024 * 1024; } this.linesPerSet = linesPerSet; if (this.linesPerSet < 1) { Debug.WriteLine("[SACache] No set-cardinality specified, configuring for N=4."); this.linesPerSet = 4; } if (this.cacheSize % this.linesPerSet != 0) { throw new System.ArgumentException("[SACache] Cache size must be an even multiple of set size."); } this.evictor = evictor; if (this.evictor == null) { Debug.WriteLine("[SACache] No cache evictor specified, using \"LRU\"."); this.evictor = new LRUEvictor <TKey, TVal>(); } this.hashGenerator = hashGenerator; if (this.hashGenerator == null) { Debug.WriteLine("[SACache] WARNING: No hash generator specified, using \"Object.GetHashCode()\". " + "Mutable key types (complex objects) may not cache properly using this!"); this.hashGenerator = new GenericHashGenerator <TKey>(); } // We're a cache, not a database - pre-allocate everything we're going to need. setCount = this.cacheSize / this.linesPerSet; entries = new CacheEntry <TKey, TVal> [this.cacheSize]; for (int i = 0; i < this.cacheSize; i++) { entries[i] = new CacheEntry <TKey, TVal>(); } }
public static void EvictorsWork( IEvictor evictor, string elementsToInsert, string elementsToGet, string expected) { var cache = new Cache <string>(4, evictor); foreach (var item in elementsToInsert.ConvertToArray(int.Parse)) { cache.Add(item, item.ToString()); } foreach (var item in elementsToGet.ConvertToArray(int.Parse)) { var value = cache.Get(item); Assert.AreEqual(item.ToString(), value); } cache.Add(99, 99.ToString()); Assert.AreEqual(expected, cache.ToString()); }
public Cache(int capacity, IEvictor evictor) { this.Capacity = capacity; this.Evictor = evictor; this.items = new Dictionary <int, T>(); }