public MemoryCacheEntry Dequeue()
        {
            MemoryCacheEntry ret = null;

            MemoryCacheEntry[] heap;
            bool locked = false;
            int  index;

            try {
                queueLock.EnterWriteLock();
                locked = true;
                heap   = GetHeapWithShrink();
                if (heap == null || heapCount == 0)
                {
                    return(null);
                }

                ret          = heap [0];
                index        = --heapCount;
                heap [0]     = heap [index];
                heap [index] = null;

                if (heapCount > 0)
                {
                    BubbleDown(heap);
                }

                return(ret);
            } finally {
                if (locked)
                {
                    queueLock.ExitWriteLock();
                }
            }
        }
Пример #2
0
        bool ExpireIfNeeded(string key, MemoryCacheEntry entry, bool needsLock = true, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Expired)
        {
            bool locked = false;

            try {
                if (entry.IsExpired)
                {
                    if (needsLock)
                    {
                        cache_lock.EnterWriteLock();
                        locked = true;
                    }

                    cache.Remove(key);
                    perfCounters.Decrement(MemoryCachePerformanceCounters.CACHE_ENTRIES);
                    entry.Removed(owner, CacheEntryRemovedReason.Expired);

                    return(true);
                }
            } finally {
                if (locked)
                {
                    cache_lock.ExitWriteLock();
                }
            }

            return(false);
        }
Пример #3
0
        long DoRemoveExpiredItems(bool needLock)
        {
            long count  = 0;
            bool locked = false;

            try {
                if (needLock)
                {
                    cache_lock.EnterWriteLock();
                    locked = true;
                }

                if (timedItems == null)
                {
                    return(0);
                }

                long             now   = DateTime.Now.Ticks;
                MemoryCacheEntry entry = timedItems.Peek();

                while (entry != null)
                {
                    if (entry.Disabled)
                    {
                        timedItems.Dequeue();
                        entry = timedItems.Peek();
                        continue;
                    }

                    if (entry.ExpiresAt > now)
                    {
                        break;
                    }

                    timedItems.Dequeue();
                    count++;
                    DoRemoveEntry(entry, true, entry.Key, CacheEntryRemovedReason.Expired);
                    entry = timedItems.Peek();
                }

                if (entry == null)
                {
                    timedItems = null;
                    expirationTimer.Dispose();
                    expirationTimer = null;
                }

                return(count);
            } finally {
                if (locked)
                {
                    cache_lock.ExitWriteLock();
                }
            }
        }
Пример #4
0
        internal void Remove(MemoryCacheEntry entry)
        {
            if (entry == null)
            {
                return;
            }

            string key = entry.Key;

            FindContainer(key).Remove(key);
        }
Пример #5
0
		public void Remove (MemoryCacheEntry entry)
		{
			if (entry == null)
				return;
			
			int hash = entry.GetHashCode ();
			LinkedListNode <MemoryCacheEntry> node;
			
			if (index.TryGetValue (hash, out node)) {
				lru.Remove (node);
				index.Remove (hash);
			}
		}
Пример #6
0
        // NOTE: this method _MUST_ be called with the write lock held
        void UpdateExpirable(MemoryCacheEntry entry)
        {
            if (timedItems == null)
            {
                timedItems = new MemoryCacheEntryPriorityQueue();
            }

            timedItems.Enqueue(entry);

            if (expirationTimer == null)
            {
                expirationTimer = new Timer(RemoveExpiredItems, null, owner.TimerPeriod, owner.TimerPeriod);
            }
        }
Пример #7
0
        public void Set(string key, object value, CacheItemPolicy policy)
        {
            bool locked = false;

            try {
                cache_lock.EnterWriteLock();
                locked = true;

                MemoryCacheEntry mce;
                bool             update = false;
                if (cache.TryGetValue(key, out mce))
                {
                    if (mce != null)
                    {
                        perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_HITS);
                        mce.Value = value;
                        mce.SetPolicy(policy);
                        if (mce.IsExpirable)
                        {
                            UpdateExpirable(mce);
                        }
                        lru.Update(mce);
                        return;
                    }

                    update = true;
                }
                perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_MISSES);
                if (policy != null)
                {
                    mce = new MemoryCacheEntry(owner, key, value,
                                               policy.AbsoluteExpiration,
                                               policy.ChangeMonitors,
                                               policy.Priority,
                                               policy.RemovedCallback,
                                               policy.SlidingExpiration,
                                               policy.UpdateCallback);
                }
                else
                {
                    mce = new MemoryCacheEntry(owner, key, value);
                }
                AddToCache(key, mce, update);
            } finally {
                if (locked)
                {
                    cache_lock.ExitWriteLock();
                }
            }
        }
Пример #8
0
        // NOTE: this must be called with the write lock held
        void DoRemoveEntry(MemoryCacheEntry entry, bool updateLRU = true, string key = null, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Removed)
        {
            if (key == null)
            {
                key = entry.Key;
            }

            cache.Remove(key);
            if (updateLRU)
            {
                lru.Remove(entry);
            }
            perfCounters.Decrement(MemoryCachePerformanceCounters.CACHE_ENTRIES);
            entry.Removed(owner, reason);
        }
Пример #9
0
        public void Remove(MemoryCacheEntry entry)
        {
            if (entry == null)
            {
                return;
            }

            int hash = entry.GetHashCode();
            LinkedListNode <MemoryCacheEntry> node;

            if (index.TryGetValue(hash, out node))
            {
                lru.Remove(node);
                index.Remove(hash);
            }
        }
Пример #10
0
        public object AddOrGetExisting(string key, object value, CacheItemPolicy policy)
        {
            bool readLocked = false, writeLocked = false;

            try {
                cache_lock.EnterUpgradeableReadLock();
                readLocked = true;

                MemoryCacheEntry entry;
                if (cache.TryGetValue(key, out entry) && entry != null)
                {
                    perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_HITS);
                    return(entry.Value);
                }
                perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_MISSES);

                cache_lock.EnterWriteLock();
                writeLocked = true;

                if (policy == null)
                {
                    entry = new MemoryCacheEntry(owner, key, value);
                }
                else
                {
                    entry = new MemoryCacheEntry(owner, key, value,
                                                 policy.AbsoluteExpiration,
                                                 policy.ChangeMonitors,
                                                 policy.Priority,
                                                 policy.RemovedCallback,
                                                 policy.SlidingExpiration,
                                                 policy.UpdateCallback);
                }

                AddToCache(key, entry);
                return(null);
            } finally {
                if (writeLocked)
                {
                    cache_lock.ExitWriteLock();
                }
                if (readLocked)
                {
                    cache_lock.ExitUpgradeableReadLock();
                }
            }
        }
Пример #11
0
		public void Update (MemoryCacheEntry entry)
		{
			if (entry == null)
				return;

			int hash = entry.GetHashCode ();
			LinkedListNode <MemoryCacheEntry> node;
			
			if (!index.TryGetValue (hash, out node)) {
				node = new LinkedListNode <MemoryCacheEntry> (entry);
				index.Add (hash, node);
			} else {
				lru.Remove (node);
				node.Value = entry;
			}
			
			lru.AddLast (node);
		}
        void BubbleDown(MemoryCacheEntry[] heap)
        {
            int index             = 0;
            int left              = 1;
            int right             = 2;
            MemoryCacheEntry item = heap [0];
            int selected          = (right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt) ? 2 : 1;

            while (selected < heapCount && heap [selected].ExpiresAt < item.ExpiresAt)
            {
                heap [index] = heap [selected];
                index        = selected;
                left         = (index << 1) + 1;
                right        = left + 1;
                selected     = right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt ? right : left;
            }
            heap [index] = item;
        }
Пример #13
0
        // NOTE: this method _MUST_ be called with the write lock held
        void AddToCache(string key, MemoryCacheEntry entry, bool update = false)
        {
            if (update)
            {
                cache [key] = entry;
            }
            else
            {
                cache.Add(key, entry);
            }
            lru.Update(entry);
            entry.Added();
            if (!update)
            {
                perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_ENTRIES);
            }

            if (entry.IsExpirable)
            {
                UpdateExpirable(entry);
            }
        }
Пример #14
0
        public void Update(MemoryCacheEntry entry)
        {
            if (entry == null)
            {
                return;
            }

            int hash = entry.GetHashCode();
            LinkedListNode <MemoryCacheEntry> node;

            if (!index.TryGetValue(hash, out node))
            {
                node = new LinkedListNode <MemoryCacheEntry> (entry);
                index.Add(hash, node);
            }
            else
            {
                lru.Remove(node);
                node.Value = entry;
            }

            lru.AddLast(node);
        }
Пример #15
0
		bool ExpireIfNeeded (string key, MemoryCacheEntry entry, bool needsLock = true, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Expired)
		{
			bool locked = false;
			
			try {
				if (entry.IsExpired) {
					if (needsLock) {
						cache_lock.EnterWriteLock ();
						locked = true;
					}
					
					cache.Remove (key);
					perfCounters.Decrement (MemoryCachePerformanceCounters.CACHE_ENTRIES);
					entry.Removed (owner, CacheEntryRemovedReason.Expired);
					
					return true;
				}
			} finally {
				if (locked)
					cache_lock.ExitWriteLock ();
			}
			
			return false;
		}
        public void Enqueue(MemoryCacheEntry item)
        {
            if (item == null)
            {
                return;
            }

            bool locked = false;

            MemoryCacheEntry[] heap;

            try {
                queueLock.EnterWriteLock();
                locked             = true;
                heap               = GetHeapWithGrow();
                heap [heapCount++] = item;
                BubbleUp(heap);
            } finally {
                if (locked)
                {
                    queueLock.ExitWriteLock();
                }
            }
        }
Пример #17
0
		public void Set (string key, object value, CacheItemPolicy policy)
		{
			bool locked = false;
			try {
				cache_lock.EnterWriteLock ();
				locked = true;

				MemoryCacheEntry mce;
				bool update = false;
				if (cache.TryGetValue (key, out mce)) {
					if (mce != null) {
						perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS);
						mce.Value = value;
						mce.SetPolicy (policy);
						if (mce.IsExpirable)
							UpdateExpirable (mce);
						lru.Update (mce);
						return;
					}

					update = true;
				}
				perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES);
				if (policy != null)
					mce = new MemoryCacheEntry (owner, key, value,
								    policy.AbsoluteExpiration,
								    policy.ChangeMonitors,
								    policy.Priority,
								    policy.RemovedCallback,
								    policy.SlidingExpiration,
								    policy.UpdateCallback);
				else
					mce = new MemoryCacheEntry (owner, key, value);
				AddToCache (key, mce, update);
			} finally {
				if (locked)
					cache_lock.ExitWriteLock ();
			}
		}
Пример #18
0
		// NOTE: this method _MUST_ be called with the write lock held
		void AddToCache (string key, MemoryCacheEntry entry, bool update = false)
		{
			if (update)
				cache [key] = entry;
			else
				cache.Add (key, entry);
			lru.Update (entry);
			entry.Added ();
			if (!update)
				perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_ENTRIES);
			
			if (entry.IsExpirable)
				UpdateExpirable (entry);
		}
Пример #19
0
		// NOTE: this method _MUST_ be called with the write lock held
		void UpdateExpirable (MemoryCacheEntry entry)
		{
			if (timedItems == null)
				timedItems = new MemoryCacheEntryPriorityQueue ();

			timedItems.Enqueue (entry);

			if (expirationTimer == null)
				expirationTimer = new Timer (RemoveExpiredItems, null, owner.TimerPeriod, owner.TimerPeriod);
		}
Пример #20
0
		public object AddOrGetExisting (string key, object value, CacheItemPolicy policy)
		{
			bool readLocked = false, writeLocked = false;
			try {
				cache_lock.EnterUpgradeableReadLock ();
				readLocked = true;

				MemoryCacheEntry entry;
				if (cache.TryGetValue (key, out entry) && entry != null) {
					perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS);
					return entry.Value;
				}
				perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES);
				
				cache_lock.EnterWriteLock ();
				writeLocked = true;

				if (policy == null)
					entry = new MemoryCacheEntry (owner, key, value);
				else
					entry = new MemoryCacheEntry (owner, key, value,
								      policy.AbsoluteExpiration,
								      policy.ChangeMonitors,
								      policy.Priority,
								      policy.RemovedCallback,
								      policy.SlidingExpiration,
								      policy.UpdateCallback);

				AddToCache (key, entry);
				return null;
			} finally {
				if (writeLocked)
					cache_lock.ExitWriteLock ();
				if (readLocked)
					cache_lock.ExitUpgradeableReadLock ();
			}
		}
Пример #21
0
		// NOTE: this must be called with the write lock held
		void DoRemoveEntry (MemoryCacheEntry entry, bool updateLRU = true, string key = null, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Removed)
		{
			if (key == null)
				key = entry.Key;

			cache.Remove (key);
			if (updateLRU)
				lru.Remove (entry);
			perfCounters.Decrement (MemoryCachePerformanceCounters.CACHE_ENTRIES);
			entry.Removed (owner, reason);
		}
		public void Enqueue (MemoryCacheEntry item)
		{
			if (item == null)
				return;

			bool locked = false;
			MemoryCacheEntry[] heap;
			
			try {
				queueLock.EnterWriteLock ();
				locked = true;
				heap = GetHeapWithGrow ();
				heap [heapCount++] = item;
				BubbleUp (heap);
			} finally {
				if (locked)
					queueLock.ExitWriteLock ();
			}
		}
		void BubbleUp (MemoryCacheEntry[] heap)
		{
			int index, parentIndex;
			MemoryCacheEntry parent, item;
			
			if (heapCount <= 1)
				return;
			
			index = heapCount - 1;
			parentIndex = (index - 1) >> 1;

			item = heap [index];
			while (index > 0) {
				parent = heap [parentIndex];
				if (heap [index].ExpiresAt >= parent.ExpiresAt)
					break;
				
				heap [index] = parent;
				index = parentIndex;
				parentIndex = (index - 1) >> 1;
			}

			heap [index] = item;
		}
		void BubbleDown (MemoryCacheEntry[] heap)
		{
			int index = 0;
			int left = 1;
			int right = 2;
			MemoryCacheEntry item = heap [0];
			int selected = (right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt) ? 2 : 1;

			while (selected < heapCount && heap [selected].ExpiresAt < item.ExpiresAt) {
				heap [index] = heap [selected];
				index = selected;
				left = (index << 1) + 1;
				right = left + 1;
				selected = right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt ? right : left;
			}
			heap [index] = item;
		}