예제 #1
0
        private static void OvercapacityCompaction(MemoryCache cache)
        {
            CoherentState coherentState = cache._coherentState; // Clear() can update the reference in the meantime
            long          currentSize   = coherentState.Size;

            cache._logger.LogDebug($"Overcapacity compaction executing. Current size {currentSize}");

            double?lowWatermark = cache._options.SizeLimit * (1 - cache._options.CompactionPercentage);

            if (currentSize > lowWatermark)
            {
                cache.Compact(currentSize - (long)lowWatermark, entry => entry.Size.Value, coherentState);
            }

            cache._logger.LogDebug($"Overcapacity compaction executed. New size {coherentState.Size}");
        }
예제 #2
0
        public void CompactLastAccessedRaceCondition()
        {
            const int   numEntries = 100;
            MemoryCache cache      = new MemoryCache(new MemoryCacheOptions());
            Random      random     = new Random();

            void FillCache()
            {
                for (int i = 0; i < numEntries; i++)
                {
                    cache.Set($"key{i}", $"value{i}");
                }
            }

            // start a few tasks to access entries in the background
            Task[] backgroundAccessTasks = new Task[Environment.ProcessorCount];
            bool   done = false;

            for (int i = 0; i < backgroundAccessTasks.Length; i++)
            {
                backgroundAccessTasks[i] = Task.Run(async() =>
                {
                    while (!done)
                    {
                        cache.TryGetValue($"key{random.Next(numEntries)}", out _);
                        await Task.Yield();
                    }
                });
            }

            for (int i = 0; i < 1000; i++)
            {
                FillCache();

                cache.Compact(1);
            }

            done = true;

            Task.WaitAll(backgroundAccessTasks);
        }