Esempio n. 1
0
 /// <summary>
 /// Removes an object from the cache with the matching cache key
 /// </summary>
 /// <param name="key"></param>
 public static void RemoveFromCache(CacheKey key, string paramString = "")
 {
     if (ConfigHelper.GetAppSettingBool(ConfigKey.TwitterCacheEnabled, false))
     {
         HttpRuntime.Cache.Remove(key.ToString() + paramString);
     }
 }
Esempio n. 2
0
 /// <summary>
 /// Returns an object from the cache with the matching cache key
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public static object GetFromCache(CacheKey key, string paramString = "")
 {
     if (ConfigHelper.GetAppSettingBool(ConfigKey.TwitterCacheEnabled, false))
         return HttpRuntime.Cache.Get(key.ToString() + paramString);
     else
         return null;
 }
Esempio n. 3
0
        /// <summary>
        /// Adds the supplied object to the cache
        /// </summary>
        /// <param name="key">The key enum to add the data under</param>
        /// <param name="cacheData">The data to add to the cache</param>
        /// <param name="cacheLength">The timeout in minutes for the cached data</param>
        public static void AddToCache(object cacheData, int cacheLength, CacheKey key, string paramString = "")
        {
            if (ConfigHelper.GetAppSettingBool(ConfigKey.TwitterCacheEnabled, false))
            {
                DateTime cacheTimeout = DateTime.Now.AddMinutes(cacheLength);

                HttpRuntime.Cache.Add(key.ToString() + paramString, cacheData, null, cacheTimeout, System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }
        }
Esempio n. 4
0
 internal abstract CacheEntry UpdateCache(
         CacheKey                cacheKey,
         CacheEntry              newEntry,
         bool                    replace,
         CacheItemRemovedReason  removedReason,
         out object              valueOld);
Esempio n. 5
0
 /// <devdoc>
 ///    <para>Removes the specified item from the cache. </para>
 /// </devdoc>
 public object Remove(string key) {
     CacheKey cacheKey = new CacheKey(key, true);
     return _cacheInternal.DoRemove(cacheKey, CacheItemRemovedReason.Removed);
 }
Esempio n. 6
0
        /*
         * Performs all operations on the cache, with the
         * exception of Clear. The arguments indicate the type of operation:
         *
         * @param key The key of the object.
         * @param newItem The new entry to be added to the cache.
         * @param replace Whether or not newEntry should replace an existing object in the cache.
         * @return The item requested. May be null.
         */
        internal override CacheEntry UpdateCache(
                CacheKey                cacheKey,
                CacheEntry              newEntry,
                bool                    replace,
                CacheItemRemovedReason  removedReason,
                out object              valueOld)
        {
            CacheEntry              entry = null;
            CacheEntry              oldEntry = null;
            bool                    expired = false;
            DateTime                utcNow;
            CacheDependency         newEntryDependency = null;
            bool                    isGet, isAdd;
            bool                    removeExpired = false;
            bool                    updateExpires = false;
            DateTime                utcNewExpires = DateTime.MinValue;
            CacheEntry.EntryState   entryState = CacheEntry.EntryState.NotInCache;
            bool                    newEntryNeedsClose = false;
            CacheItemRemovedReason  newEntryRemovedReason = CacheItemRemovedReason.Removed;

            valueOld = null;
            isGet = !replace && newEntry == null;
            isAdd = !replace && newEntry != null;

            /*
             * Perform update of cache data structures in a series to
             * avoid overlapping locks.
             *
             * First, update the hashtable. The hashtable is the place
             * that guarantees what is in or out of the cache.
             *
             * Loop here to remove expired items in a Get or Add, where
             * we can't otherwise delete an item.
             */
            for (;;) {
                if (removeExpired) {
                    Debug.Trace("CacheUpdate", "Removing expired item found in Get: " + cacheKey);
                    UpdateCache(cacheKey, null, true, CacheItemRemovedReason.Expired, out valueOld);
                    removeExpired = false;
                }

                entry = null;
                utcNow = DateTime.UtcNow;

                if (_useInsertBlock && newEntry != null && newEntry.HasUsage() /* HasUsage() means it's not NonRemovable */) {
                    bool insertBlockReleased = WaitInsertBlock();

#if DBG
                    if (!insertBlockReleased) {
                        Debug.Trace("CacheUpdateWaitFailed", "WaitInsertBlock failed.");
                    }
#endif
                }

                // the _entries hashtable supports multiple readers or one writer
                bool isLockEntered = false;
                if (!isGet) {
                    Monitor.Enter(_lock, ref isLockEntered);
                }
                try {
                    entry = (CacheEntry) _entries[cacheKey];
                    Debug.Trace("CacheUpdate", "Entry " + ((entry != null) ? "found" : "not found") + "in hashtable: " + cacheKey);

                    if (entry != null) {
                        entryState = entry.State;

                        // If isGet == true, we are not hold any lock and so entryState can be anything
                        Debug.Assert(
                            isGet ||
                            entryState == CacheEntry.EntryState.AddingToCache ||
                            entryState == CacheEntry.EntryState.AddedToCache,
                            "entryState == CacheEntry.EntryState.AddingToCache || entryState == CacheEntry.EntryState.AddedToCache");

                        expired = (_cacheCommon._enableExpiration) && (entry.UtcExpires < utcNow);
                        if (expired) {
                            if (isGet) {
                                /*
                                 * If the expired item is Added to the cache, remove it now before
                                 * its expiration timer fires up to a minute in the future.
                                 * Otherwise, just return null to indicate the item is not available.
                                 */
                                if (entryState == CacheEntry.EntryState.AddedToCache) {
                                    removeExpired = true;
                                    continue;
                                }

                                entry = null;
                            }
                            else {
                                /*
                                 * If it's a call to Add, replace the item
                                 * when it has expired.
                                 */
                                replace = true;

                                /*
                                 * Change the removed reason.
                                 */
                                removedReason = CacheItemRemovedReason.Expired;
                            }
                        }
                        else {
                            updateExpires = (_cacheCommon._enableExpiration) && (entry.SlidingExpiration > TimeSpan.Zero);
                        }
                    }

                    /*
                     * Avoid running unnecessary code in a Get request by this simple test:
                     */
                    if (!isGet) {
                        /*
                         * Remove an item from the hashtable.
                         */
                        if (replace && entry != null) {
                            bool doRemove = (entryState != CacheEntry.EntryState.AddingToCache);
                            if (doRemove) {
                                oldEntry = entry;

                                oldEntry.State = CacheEntry.EntryState.RemovingFromCache;

                                _entries.Remove(oldEntry);
                                Debug.Trace("CacheUpdate", "Entry removed from hashtable: " + cacheKey);
                            }
                            else {
                                /*
                                 * If we're removing and couldn't remove the old item
                                 * because its state was AddingToCache, return null
                                 * to indicate failure.
                                 */
                                if (newEntry == null) {
                                    Debug.Trace("CacheUpdate", "Removal from hashtable failed: " + cacheKey);
                                    entry = null;
                                }
                            }
                        }

                        /*
                         * Add an item to the hashtable.
                         */
                        if (newEntry != null) {
                            bool doAdd = true;

                            if (entry != null) {
                                if (oldEntry == null) {
                                    /*
                                     * We could not remove the existing entry,
                                     * either because it simply exists and replace == false,
                                     * or replace == true and it's state was AddingToCache when
                                     * we tried to remove it.
                                    */
                                    doAdd = false;
                                    newEntryRemovedReason = CacheItemRemovedReason.Removed;
                                }

#if DBG
                                if (!doAdd) {
                                    Debug.Trace("CacheUpdate", "Insertion into hashtable failed because old entry was not removed: " + cacheKey);
                                }
#endif
                            }


                            if (doAdd) {
                                /* non-definitive check */
                                newEntryDependency = newEntry.Dependency;
                                if (newEntryDependency != null) {
                                    if (newEntryDependency.HasChanged) {
                                        doAdd = false;
                                        newEntryRemovedReason = CacheItemRemovedReason.DependencyChanged;
                                    }

#if DBG
                                    if (!doAdd) {
                                        Debug.Trace("CacheUpdate", "Insertion into hashtable failed because dependency changed: " + cacheKey);
                                    }
#endif
                                }
                            }

                            if (doAdd) {
                                newEntry.State = CacheEntry.EntryState.AddingToCache;
                                _entries.Add(newEntry, newEntry);

                                /*
                                 * If this is an Add operation, indicate success
                                 * by returning null.
                                 */
                                if (isAdd) {
                                    Debug.Assert(entry == null || expired, "entry == null || expired");
                                    entry = null;
                                }
                                else {
                                    /*
                                     * Indicate success by returning the inserted entry.
                                     */
                                    entry = newEntry;
                                }

                                Debug.Trace("CacheUpdate", "Entry added to hashtable: " + cacheKey);
                            }
                            else {
                                if (!isAdd) {
                                    /*
                                     * If we failed for an Insert, indicate failure by returning null.
                                     */
                                    entry = null;
                                    newEntryNeedsClose = true;
                                }
                                else {
                                    /*
                                     * If we failed for an Add (e.g. Dependency has changed),
                                     * return the existing value. If existing value is null,
                                     * we have to close the newEntry ourselves.  Otherwise, we'll
                                     * return non-null and the caller should close the item.
                                     */
                                    newEntryNeedsClose = (entry == null);
                                }

                                /*
                                 * If newEntry cannot be inserted, and it does not need to be
                                 * closed, set it to null so that we don't insert it later.
                                 * Leave it non-null when it needs to be closed that that we
                                 * can close it.
                                 */
                                if (!newEntryNeedsClose) {
                                    newEntry = null;
                                }

                            }
                        }
                    }

                    break;
                }
                finally {
                    if (isLockEntered) {
                        Monitor.Exit(_lock);
                    }
                }
            }

            /*
             * Since we want Get to be fast, check here for a get without
             * alteration to cache.
             */
            if (isGet) {
                if (entry != null) {
                    if (updateExpires) {
                        utcNewExpires = utcNow + entry.SlidingExpiration;
                        if (utcNewExpires - entry.UtcExpires >= CacheExpires.MIN_UPDATE_DELTA || utcNewExpires < entry.UtcExpires) {
                            _expires.UtcUpdate(entry, utcNewExpires);
                        }
                    }

                    UtcUpdateUsageRecursive(entry, utcNow);
                }

                if (cacheKey.IsPublic) {
                    PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_RATIO_BASE);
                    if (entry != null) {
                        PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_HITS);
                    }
                    else {
                        PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_MISSES);
                    }
                }

                PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_RATIO_BASE);
                if (entry != null) {
                    PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_HITS);
                }
                else {
                    PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_MISSES);
                }

#if DBG
                if (entry != null) {
                    Debug.Trace("CacheUpdate", "Cache hit: " + cacheKey);
                }
                else {
                    Debug.Trace("CacheUpdate", "Cache miss: " + cacheKey);
                }
#endif

            }
            else {
                int totalDelta = 0;
                int publicDelta = 0;
                int totalTurnover = 0;
                int publicTurnover = 0;

                if (oldEntry != null) {
                    if (oldEntry.InExpires()) {
                        _expires.Remove(oldEntry);
                    }

                    if (oldEntry.InUsage()) {
                        _usage.Remove(oldEntry);
                    }

                    Debug.Assert(oldEntry.State == CacheEntry.EntryState.RemovingFromCache, "oldEntry.State == CacheEntry.EntryState.RemovingFromCache");
                    oldEntry.State = CacheEntry.EntryState.RemovedFromCache;
                    valueOld = oldEntry.Value;

                    totalDelta--;
                    totalTurnover++;
                    if (oldEntry.IsPublic) {
                        publicDelta--;
                        publicTurnover++;
                    }

#if DBG
                    Debug.Trace("CacheUpdate", "Entry removed from cache, reason=" + removedReason + ": " + (CacheKey) oldEntry);
#endif
                }

                if (newEntry != null) {
                    if (newEntryNeedsClose) {
                        // Call close if newEntry could not be added.
                        newEntry.State = CacheEntry.EntryState.RemovedFromCache;
                        newEntry.Close(newEntryRemovedReason);
                        newEntry = null;
                    }
                    else {
                        Debug.Assert(!newEntry.InExpires());
                        Debug.Assert(!newEntry.InUsage());

                        if (_cacheCommon._enableExpiration && newEntry.HasExpiration()) {
                            _expires.Add(newEntry);
                        }

                        if (    _cacheCommon._enableMemoryCollection && newEntry.HasUsage() &&
                                (   // Don't bother to set usage if it's going to expire very soon
                                    !newEntry.HasExpiration() ||
                                    newEntry.SlidingExpiration > TimeSpan.Zero ||
                                    newEntry.UtcExpires - utcNow >= CacheUsage.MIN_LIFETIME_FOR_USAGE)) {

                            _usage.Add(newEntry);
                        }

                        newEntry.State = CacheEntry.EntryState.AddedToCache;

                        Debug.Trace("CacheUpdate", "Entry added to cache: " + (CacheKey)newEntry);

                        totalDelta++;
                        totalTurnover++;
                        if (newEntry.IsPublic) {
                            publicDelta++;
                            publicTurnover++;
                        }
                    }
                }

                // Call close after the newEntry has been fully added to the cache,
                // so the OnRemoveCallback can take a dependency on the newly inserted item.
                if (oldEntry != null) {
                    oldEntry.Close(removedReason);
                }

                // Delay monitoring change events until the oldEntry has been completely removed
                // from the cache, and its OnRemoveCallback called. This way we won't call the
                // OnRemoveCallback for newEntry before doing so for oldEntry.
                if (newEntry != null) {
                    // listen to change events
                    newEntry.MonitorDependencyChanges();

                    /*
                     * NB: We have to check for dependency changes after we add the item
                     * to cache, because otherwise we may not remove it if it changes
                     * between the time we check for a dependency change and the time
                     * we set the AddedToCache bit. The worst that will happen is that
                     * a get can occur on an item that has changed, but that can happen
                     * anyway. The important thing is that we always remove an item that
                     * has changed.
                     */
                    if (newEntryDependency != null && newEntryDependency.HasChanged) {
                        Remove(newEntry, CacheItemRemovedReason.DependencyChanged);
                    }
                }
                
                // update counts and counters
                if (totalDelta == 1) {
                    Interlocked.Increment(ref _totalCount);
                    PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_ENTRIES);
                }
                else if (totalDelta == -1) {
                    Interlocked.Decrement(ref _totalCount);
                    PerfCounters.DecrementCounter(AppPerfCounter.TOTAL_CACHE_ENTRIES);
                }

                if (publicDelta == 1) {
                    Interlocked.Increment(ref _publicCount);
                    PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_ENTRIES);
                }
                else if (publicDelta == -1) {
                    Interlocked.Decrement(ref _publicCount);
                    PerfCounters.DecrementCounter(AppPerfCounter.API_CACHE_ENTRIES);
                }

                if (totalTurnover > 0) {
                    PerfCounters.IncrementCounterEx(AppPerfCounter.TOTAL_CACHE_TURNOVER_RATE, totalTurnover);
                }

                if (publicTurnover > 0) {
                    PerfCounters.IncrementCounterEx(AppPerfCounter.API_CACHE_TURNOVER_RATE, publicTurnover);
                }
            }

            return entry;
        }
Esempio n. 7
0
        /*
         * Remove an item from the cache, with a specific reason.
         * This is package access so only the cache can specify
         * a reason other than REMOVED.
         *
         * @param key The key for the item.
         * @exception ArgumentException
         */
        internal object DoRemove(CacheKey cacheKey, CacheItemRemovedReason reason)  {
            object      valueOld;

            UpdateCache(cacheKey, null, true, reason, out valueOld);

#if DBG
            if (valueOld != null) {
                Debug.Trace("CacheAPIRemove", "Cache.Remove succeeded, reason=" + reason + ": " + cacheKey);
            }
            else {
                Debug.Trace("CacheAPIRemove", "Cache.Remove failed, reason=" + reason + ": " + cacheKey);
            }
#endif

            return valueOld;
        }
Esempio n. 8
0
 internal object Remove(CacheKey cacheKey, CacheItemRemovedReason reason)  {
     return DoRemove(cacheKey, reason);
 }
Esempio n. 9
0
 internal object Remove(string key) {
     CacheKey cacheKey = new CacheKey(key, false);
     return DoRemove(cacheKey, CacheItemRemovedReason.Removed);
 }
 internal object DoRemove(CacheKey cacheKey, CacheItemRemovedReason reason)
 {
     object obj2;
     this.UpdateCache(cacheKey, null, true, reason, out obj2);
     return obj2;
 }
Esempio n. 11
0
		public void SmartDelete(List<ThreadUsr.StatusEnum> threadStatusesToChange, Model.Entities.ObjectType? statusChangeObjectType, int? statusChangeObjectK)
		{
			string memcachedKey = new Caching.CacheKey(Caching.CacheKeyPrefix.UpdateThreadUsrJobStatus, "UsrK", this.K.ToString(), "StatusChangeObjectType", statusChangeObjectType.ToString(), "StatusChangeObjectK", statusChangeObjectK.ToString()).ToString();
			SmartDeleteThreadUsrJob sdtuj = new SmartDeleteThreadUsrJob(this.K, threadStatusesToChange, statusChangeObjectType, statusChangeObjectK, memcachedKey);
			sdtuj.ExecuteAsynchronously();
		}
Esempio n. 12
0
		public void UpdateThreadUsrs(ThreadUsr.StatusEnum changeStatus, List<ThreadUsr.StatusEnum> threadStatusesToChange, Model.Entities.ObjectType? statusChangeObjectType, int? statusChangeObjectK)
		{
			string memcachedKey = new Caching.CacheKey(Caching.CacheKeyPrefix.UpdateThreadUsrJobStatus, "UsrK", this.K.ToString(), "StatusChangeObjectType", statusChangeObjectType.ToString(), "StatusChangeObjectK", statusChangeObjectK.ToString()).ToString();
			UpdateThreadUsrJob utuj = new UpdateThreadUsrJob(this.K, changeStatus, threadStatusesToChange, statusChangeObjectType, statusChangeObjectK, memcachedKey);
			utuj.ExecuteAsynchronously();

			//Update uThreadUsr = new Update();
			//uThreadUsr.Table = TablesEnum.ThreadUsr;
			//uThreadUsr.Changes.Add(new Assign(ThreadUsr.Columns.Status, changeStatus));
			//uThreadUsr.Changes.Add(new Assign(ThreadUsr.Columns.StatusChangeDateTime, Time.Now));
			//uThreadUsr.Where = new Q(ThreadUsr.Columns.UsrK, this.K);

			//if (threadStatusesToChange != null && threadStatusesToChange.Count > 0)
			//{
			//    Or statusOr = new Or();
			//    foreach (ThreadUsr.StatusEnum statusEnum in threadStatusesToChange)
			//    {
			//        statusOr = new Or(statusOr,
			//                        new Q(ThreadUsr.Columns.Status, statusEnum));
			//    }
			//    uThreadUsr.Where = new And(uThreadUsr.Where,
			//                               statusOr);
			//}
			//else
			//    throw new Exception("Usr.UpdateThreadUsrs(): Invalid list of ThreadUsr.StatusEnum to change.");


			//if (statusChangeObjectType != null)
			//{
			//    if (statusChangeObjectType.Value == Model.Entities.ObjectType.Usr)
			//    {
			//        // do nothing here
			//    }
			//    else
			//    {
			//        uThreadUsr.Where = new And(uThreadUsr.Where,
			//                                   new Q(ThreadUsr.Columns.StatusChangeObjectType, statusChangeObjectType.Value));
			//    }

			//    if (statusChangeObjectK != null)
			//    {
			//        if (statusChangeObjectType.Value == Model.Entities.ObjectType.Usr)
			//        {
			//            uThreadUsr.Where = new And(uThreadUsr.Where,
			//                                       new Q(ThreadUsr.Columns.InvitingUsrK, statusChangeObjectK.Value));
			//        }
			//        else
			//        {
			//            uThreadUsr.Where = new And(uThreadUsr.Where,
			//                                       new Q(ThreadUsr.Columns.StatusChangeObjectK, statusChangeObjectK.Value));
			//        }
			//    }
			//}
			//uThreadUsr.CommandTimeout = 90;
			//uThreadUsr.Run();
		}
Esempio n. 13
0
        internal override CacheEntry UpdateCache(CacheKey cacheKey,
                                                 CacheEntry newEntry,
                                                 bool replace,
                                                 CacheItemRemovedReason removedReason,
                                                 out object valueOld) {
            valueOld = null;
            CacheEntry entry = null;
            string key = cacheKey.Key;
            bool isPublic = cacheKey.IsPublic;
            if (_disposed) {
                return null;
            }

            MemoryCache cache = (isPublic) ? _cachePublic : _cacheInternal;
            if (newEntry == null && !replace) {
                // get
                object o = cache.Get(key);
                if (o != null) {
                    entry = new CacheEntry(key, o, null, null, 
                                           Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
                                           CacheItemPriority.Default, isPublic);
                    entry.State = CacheEntry.EntryState.AddedToCache;
                }
            }
            else if (newEntry != null && replace) {
                // set
                try {
                }
                finally {
                    // prevent ThreadAbortEx from interrupting these calls
                    CacheItemPolicy policy = GetPolicy(newEntry);
                    cache.Set(key, newEntry.Value, policy);
                }
            }
            else if (newEntry != null && !replace) {
                // add
                try {
                }
                finally {
                    // prevent ThreadAbortEx from interrupting these calls
                    CacheItemPolicy policy = GetPolicy(newEntry);
                    Object o = cache.AddOrGetExisting(key, newEntry.Value, policy);
                    if (o != null) {
                        entry = new CacheEntry(key, o, null, null, 
                                               Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
                                               CacheItemPriority.Default, isPublic);
                        entry.State = CacheEntry.EntryState.AddedToCache;
                    }
                }
            }
            else {
                // remove
                valueOld = cache.Remove(key);
            }
            return entry;
        }
Esempio n. 14
0
        internal object DoGet(bool isPublic, string key, CacheGetOptions getOptions) {
            CacheEntry  entry;
            CacheKey    cacheKey;
            object      dummy;

            cacheKey = new CacheKey(key, isPublic);
            entry = UpdateCache(cacheKey, null, false, CacheItemRemovedReason.Removed, out dummy);
            if (entry != null) {
                if ((getOptions & CacheGetOptions.ReturnCacheEntry) != 0) {
                    return entry;
                }
                else {
                    return entry.Value;
                }
            }
            else {
                return null;
            }
        }
 internal object DoGet(bool isPublic, string key, CacheGetOptions getOptions)
 {
     object obj2;
     CacheKey cacheKey = new CacheKey(key, isPublic);
     CacheEntry entry = this.UpdateCache(cacheKey, null, false, CacheItemRemovedReason.Removed, out obj2);
     if (entry == null)
     {
         return null;
     }
     if ((getOptions & CacheGetOptions.ReturnCacheEntry) != CacheGetOptions.None)
     {
         return entry;
     }
     return entry.Value;
 }
 internal override CacheEntry UpdateCache(CacheKey cacheKey, CacheEntry newEntry, bool replace, CacheItemRemovedReason removedReason, out object valueOld)
 {
     int hashCode = cacheKey.Key.GetHashCode();
     return this.GetCacheSingle(hashCode).UpdateCache(cacheKey, newEntry, replace, removedReason, out valueOld);
 }
        internal override CacheEntry UpdateCache(CacheKey cacheKey, CacheEntry newEntry, bool replace, CacheItemRemovedReason removedReason, out object valueOld)
        {
            CacheEntry cacheEntry = null;
            CacheEntry key = null;
            CacheDependency dependency = null;
            bool flag4 = false;
            bool flag5 = false;
            DateTime minValue = DateTime.MinValue;
            CacheEntry.EntryState notInCache = CacheEntry.EntryState.NotInCache;
            bool flag6 = false;
            CacheItemRemovedReason removed = CacheItemRemovedReason.Removed;
            valueOld = null;
            bool flag2 = !replace && (newEntry == null);
            bool flag3 = !replace && (newEntry != null);
        Label_003E:
            if (flag4)
            {
                this.UpdateCache(cacheKey, null, true, CacheItemRemovedReason.Expired, out valueOld);
                flag4 = false;
            }
            cacheEntry = null;
            DateTime utcNow = DateTime.UtcNow;
            if ((this._useInsertBlock && (newEntry != null)) && newEntry.HasUsage())
            {
                this.WaitInsertBlock();
            }
            bool lockTaken = false;
            if (!flag2)
            {
                Monitor.Enter(this._lock, ref lockTaken);
            }
            try
            {
                cacheEntry = (CacheEntry) this._entries[cacheKey];
                if (cacheEntry != null)
                {
                    notInCache = cacheEntry.State;
                    if (base._cacheCommon._enableExpiration && (cacheEntry.UtcExpires < utcNow))
                    {
                        if (flag2)
                        {
                            if (notInCache == CacheEntry.EntryState.AddedToCache)
                            {
                                flag4 = true;
                                goto Label_003E;
                            }
                            cacheEntry = null;
                        }
                        else
                        {
                            replace = true;
                            removedReason = CacheItemRemovedReason.Expired;
                        }
                    }
                    else
                    {
                        flag5 = base._cacheCommon._enableExpiration && (cacheEntry.SlidingExpiration > TimeSpan.Zero);
                    }
                }
                if (!flag2)
                {
                    if (replace && (cacheEntry != null))
                    {
                        if (notInCache != CacheEntry.EntryState.AddingToCache)
                        {
                            key = cacheEntry;
                            key.State = CacheEntry.EntryState.RemovingFromCache;
                            this._entries.Remove(key);
                        }
                        else if (newEntry == null)
                        {
                            cacheEntry = null;
                        }
                    }
                    if (newEntry != null)
                    {
                        bool flag9 = true;
                        if ((cacheEntry != null) && (key == null))
                        {
                            flag9 = false;
                            removed = CacheItemRemovedReason.Removed;
                        }
                        if (flag9)
                        {
                            dependency = newEntry.Dependency;
                            if ((dependency != null) && dependency.HasChanged)
                            {
                                flag9 = false;
                                removed = CacheItemRemovedReason.DependencyChanged;
                            }
                        }
                        if (flag9)
                        {
                            newEntry.State = CacheEntry.EntryState.AddingToCache;
                            this._entries.Add(newEntry, newEntry);
                            if (flag3)
                            {
                                cacheEntry = null;
                            }
                            else
                            {
                                cacheEntry = newEntry;
                            }
                        }
                        else
                        {
                            if (!flag3)
                            {
                                cacheEntry = null;
                                flag6 = true;
                            }
                            else
                            {
                                flag6 = cacheEntry == null;
                            }
                            if (!flag6)
                            {
                                newEntry = null;
                            }
                        }
                    }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(this._lock);
                }
            }
            if (flag2)
            {
                if (cacheEntry != null)
                {
                    if (flag5)
                    {
                        minValue = utcNow + cacheEntry.SlidingExpiration;
                        if (((minValue - cacheEntry.UtcExpires) >= CacheExpires.MIN_UPDATE_DELTA) || (minValue < cacheEntry.UtcExpires))
                        {
                            this._expires.UtcUpdate(cacheEntry, minValue);
                        }
                    }
                    this.UtcUpdateUsageRecursive(cacheEntry, utcNow);
                }
                if (cacheKey.IsPublic)
                {
                    PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_RATIO_BASE);
                    if (cacheEntry != null)
                    {
                        PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_HITS);
                    }
                    else
                    {
                        PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_MISSES);
                    }
                }
                PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_RATIO_BASE);
                if (cacheEntry != null)
                {
                    PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_HITS);
                    return cacheEntry;
                }
                PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_MISSES);
                return cacheEntry;
            }
            int num = 0;
            int num2 = 0;
            int delta = 0;
            int num4 = 0;
            if (key != null)
            {
                if (key.InExpires())
                {
                    this._expires.Remove(key);
                }
                if (key.InUsage())
                {
                    this._usage.Remove(key);
                }
                key.State = CacheEntry.EntryState.RemovedFromCache;
                valueOld = key.Value;
                num--;
                delta++;
                if (key.IsPublic)
                {
                    num2--;
                    num4++;
                }
            }
            if (newEntry != null)
            {
                if (flag6)
                {
                    newEntry.State = CacheEntry.EntryState.RemovedFromCache;
                    newEntry.Close(removed);
                    newEntry = null;
                }
                else
                {
                    if (base._cacheCommon._enableExpiration && newEntry.HasExpiration())
                    {
                        this._expires.Add(newEntry);
                    }
                    if ((base._cacheCommon._enableMemoryCollection && newEntry.HasUsage()) && ((!newEntry.HasExpiration() || (newEntry.SlidingExpiration > TimeSpan.Zero)) || ((newEntry.UtcExpires - utcNow) >= CacheUsage.MIN_LIFETIME_FOR_USAGE)))
                    {
                        this._usage.Add(newEntry);
                    }
                    newEntry.State = CacheEntry.EntryState.AddedToCache;
                    num++;
                    delta++;
                    if (newEntry.IsPublic)
                    {
                        num2++;
                        num4++;
                    }
                }
            }
            if (key != null)
            {
                key.Close(removedReason);
            }
            if (newEntry != null)
            {
                newEntry.MonitorDependencyChanges();
                if ((dependency != null) && dependency.HasChanged)
                {
                    base.Remove(newEntry, CacheItemRemovedReason.DependencyChanged);
                }
            }
            switch (num)
            {
                case 1:
                    Interlocked.Increment(ref this._totalCount);
                    PerfCounters.IncrementCounter(AppPerfCounter.TOTAL_CACHE_ENTRIES);
                    break;

                case -1:
                    Interlocked.Decrement(ref this._totalCount);
                    PerfCounters.DecrementCounter(AppPerfCounter.TOTAL_CACHE_ENTRIES);
                    break;
            }
            switch (num2)
            {
                case 1:
                    Interlocked.Increment(ref this._publicCount);
                    PerfCounters.IncrementCounter(AppPerfCounter.API_CACHE_ENTRIES);
                    break;

                case -1:
                    Interlocked.Decrement(ref this._publicCount);
                    PerfCounters.DecrementCounter(AppPerfCounter.API_CACHE_ENTRIES);
                    break;
            }
            if (delta > 0)
            {
                PerfCounters.IncrementCounterEx(AppPerfCounter.TOTAL_CACHE_TURNOVER_RATE, delta);
            }
            if (num4 > 0)
            {
                PerfCounters.IncrementCounterEx(AppPerfCounter.API_CACHE_TURNOVER_RATE, num4);
            }
            return cacheEntry;
        }