예제 #1
0
        /// <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>();
            }
        }
예제 #2
0
        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());
        }
예제 #3
0
 public Cache(int capacity, IEvictor evictor)
 {
     this.Capacity = capacity;
     this.Evictor  = evictor;
     this.items    = new Dictionary <int, T>();
 }