public async void AddOrUpdate(string key, object value)
        {
            SemaphoreSlim item_lock = _locks.GetOrAdd(key, k => new SemaphoreSlim(1, 1));
            await item_lock.WaitAsync();

            try
            {
                var cacheItemNode = new CacheItemNode(key, value);
                if (_memoryCache.Contains(key))
                {
                    CacheItemNode source = (CacheItemNode)_memoryCache.Get(key);
                    _lRUQueue.Remove(source);
                    _lRUQueue.MoveToFront(cacheItemNode);
                    _memoryCache.Remove(key);
                    _memoryCache.Set(key, cacheItemNode, _policy);
                    OnUpdate(source, cacheItemNode);
                }
                else
                {
                    OnAdd(key);
                    _memoryCache.Set(key, cacheItemNode, _policy);
                    _lRUQueue.MoveToFront(cacheItemNode);
                    // For DEBUG purpose
                    Console.WriteLine($"LRU queue state = {_lRUQueue.QueueState()}");
                    Console.WriteLine($"Cache size = {Count}");
                }
            }
            finally
            {
                item_lock.Release();
            }
        }
Esempio n. 2
0
 public LRUQueue()
 {
     Head          = new CacheItemNode(default(String), null);
     Tail          = new CacheItemNode(default(String), null);
     Head.Next     = Tail;
     Tail.Previous = Head;
 }
Esempio n. 3
0
        public CacheItemNode RemoveLast()
        {
            CacheItemNode node = Tail.Previous;

            Tail.Previous      = node.Previous;
            node.Previous.Next = Tail;
            node.Next          = null;
            node.Previous      = null;
            return(node);
        }
Esempio n. 4
0
 public CacheItemNode Remove(CacheItemNode node)
 {
     if (node.Next != null && node.Previous != null)
     {
         node.Previous.Next = node.Next;
         node.Next.Previous = node.Previous;
     }
     node.Next     = null;
     node.Previous = null;
     return(node);
 }
Esempio n. 5
0
 public void MoveToFront(CacheItemNode node)
 {
     if (node.Next != null && node.Previous != null)
     {
         node.Previous.Next = node.Next;
         node.Next.Previous = node.Previous;
     }
     node.Next          = Head.Next;
     Head.Next.Previous = node;
     node.Previous      = Head;
     Head.Next          = node;
 }
Esempio n. 6
0
        public string QueueState()
        {
            StringBuilder strb = new StringBuilder();
            CacheItemNode node = Head.Next;

            while (node.Next != null)
            {
                if (node != null)
                {
                    strb.Append($"{node.Key}:{node.Value.ToString()}, ");
                }
                node = node.Next;
            }
            return(strb.ToString());
        }
 public static void OnAdd(string key)
 {
     if (Count >= _capacity)
     {
         CacheItemNode cin = _lRUQueue.RemoveLast();
         _memoryCache.Remove(cin.Key);
         // To ensure that we keep consistency between items in Cache
         // and in _locks dictionary, we remove the entry for the evited
         // key in _locks.
         if (!cin.Key.Equals(key))
         {
             SemaphoreSlim semaphore;
             _locks.TryRemove(key, out semaphore);
         }
     }
 }
        public bool TryGet(string key, out object result)
        {
            CacheItemNode cacheItemNode = null;

            if (_memoryCache.Contains(key))
            {
                cacheItemNode = (CacheItemNode)_memoryCache[key];
                _lRUQueue.MoveToFront(cacheItemNode);
                result = cacheItemNode.Value;
                return(true);
            }
            else
            {
                result = null;
                return(false);
            }
        }
 public static void OnUpdate(CacheItemNode source, CacheItemNode updated)
 {
     Console.WriteLine($"Key Updated: {source.Key}, Item: (Original: {source.Value}, Updated: {updated.Value})");
 }
Esempio n. 10
0
 public CacheItemNode(string key, object value) : base(key, value)
 {
     Previous = null;
     Next     = null;
 }