public void Constructor_Failures()
        {
            NWayMemoryCache<string, double> c;

            try
            {
                c = new NWayMemoryCache<string, double>(0, 1000);
                Assert.Fail("Should have thrown.");
            }
            catch (ArgumentOutOfRangeException e)
            {
                Assert.IsTrue(e.Message.ToLower().Contains("n is less than 1"));
            }

            try
            {
                c = new NWayMemoryCache<string, double>(1000, 0);
                Assert.Fail("Should have thrown.");
            }
            catch (ArgumentOutOfRangeException e)
            {
                Assert.IsTrue(e.Message.ToLower().Contains("no values in the cache"));
            }

            try
            {
                c = new NWayMemoryCache<string, double>(2, 1);
                Assert.Fail("Should have thrown.");
            }
            catch (ArgumentException e)
            {
                Assert.IsTrue(e.Message.ToLower().Contains("maximum of 1 value(s)"));
            }
        }
        public void Constructor_Sanity()
        {
            //Interesting values.
            var c = new NWayMemoryCache<string,double>(1, 1);
            Assert.AreEqual(1, c.N);
            Assert.AreEqual(1, c.MaxValues);

            c = new NWayMemoryCache<string, double>(1, 2);
            Assert.AreEqual(1, c.N);
            Assert.AreEqual(2, c.MaxValues);

            c = new NWayMemoryCache<string, double>(2, 7);
            Assert.AreEqual(2, c.N);
            Assert.AreEqual(8, c.MaxValues);
        }
        public void Extensibility()
        {
            //Use a cache entry generator which adds a new field, "Assigned" to CacheEntry.
            var c = new NWayMemoryCache<string, double>(
                2, 2,
                cacheEntryGenerator: (keyId, val) => new CustomCacheEntry<double>(keyId, val)
            );

            //Set a custom replacement strategy where we boot out the newest "Assigned" record
            //(as opposed to the default LRU record).
            c.AssignReplacementStrategy(block => block
                .ToList()
                .ConvertAll(ce => (CustomCacheEntry<double>)ce)
                .OrderByDescending(cce => cce.Assigned)
                .First());

            //Now check that it works.
            c["01"] = 1.0;
            Thread.Sleep(100);
            Assert.IsTrue(c.ContainsKey("01"));

            c["02"] = 2.0;
            Thread.Sleep(100);
            Assert.IsTrue(c.ContainsKey("01"));
            Assert.IsTrue(c.ContainsKey("02"));

            c["03"] = 3.0;
            Thread.Sleep(100);
            Assert.IsTrue(c.ContainsKey("01"));
            Assert.IsTrue(!c.ContainsKey("02"));
            Assert.IsTrue(c.ContainsKey("03"));

            c["04"] = 4.0;
            Thread.Sleep(100);
            Assert.IsTrue(c.ContainsKey("01"));
            Assert.IsTrue(!c.ContainsKey("02"));
            Assert.IsTrue(!c.ContainsKey("03"));
            Assert.IsTrue(c.ContainsKey("04"));
        }
        public void Sanity()
        {
            //Interesting values.
            var c = new NWayMemoryCache<string, double>(2, 6);

            //Fill up every slot in the cache
            for (var i = 0; i < 6; i++)
            {
                var key = i.ToString() + "S";
                var val = (double)i;

                Assert.IsTrue(!c.ContainsKey(key));
                c[key] = val;
                Assert.IsTrue(c.ContainsKey(key));
                Assert.AreEqual(val, c[key]);
            }

            //Default eviction algorithm will kick out key == "0S"
            Assert.IsTrue(c.ContainsKey("0S"));
            c["full"] = 24.0;
            Assert.IsTrue(c.ContainsKey("full"));
            Assert.AreEqual(24.0, c["full"]);
            Assert.IsTrue(!c.ContainsKey("0S"));

            //Remove(...)
            c.Remove(null);
            Assert.IsTrue(! c.ContainsKey(null));

            //Clear(...)
            Assert.IsTrue(c.ContainsKey("full"));
            c.Clear();
            Assert.IsTrue(! c.ContainsKey("full"));
        }