/// <summary> /// Set inserts or updates an existing cache entry with the given key. /// If eviction policy is null, a Sliding Expiration policy with five minute /// timespan will be used. VirtualCache doesn't support regions thus, regionName /// will be ignored and defaults to null. /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="policy"></param> /// <param name="regionName"></param> public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null) { if (key == null) { throw new ArgumentNullException("key"); } if (value == null) { throw new ArgumentNullException("value"); } if (policy == null) { policy = DefaultPolicy; } var now = GetCurrentDate(0); var entry = new CacheEntry(policy, now) { Value = value }; var cacheKey = new CacheKey(key) { TimeStamp = now }; _store.Locker.Invoke(() => { #region update block if (_store.AddIfNotExist(cacheKey, entry)) { return; } // if priotiry is not removable, just update the store w/ value if (entry.NonExpiring) { _store.CurrentValue.Value = value; return; } entry = _store.CurrentValue; entry.Value = value; if (!entry.IsExpired(now)) { // slide the expire time... if (entry.SlidingExpiration > 0) { entry.ExpirationTime = GetCurrentDate(entry.SlidingExpiration); if (!_store.IsDataInKeySegment) { _store.CurrentValue = entry; } } return; } // adjust policy (set to slide every 5 mins) of the expired item to accomodate this update... if (entry.SlidingExpiration == 0) { entry.SlidingExpiration = TimeSpan.TicksPerMinute * 5; } entry.ExpirationTime = GetCurrentDate(entry.SlidingExpiration); if (!_store.IsDataInKeySegment) { _store.CurrentValue = entry; } return; #region for removal //if (_store.AddIfNotExist(cacheKey, ce)) // return; //// update the store... //cacheKey.TimeStamp = _store.CurrentKey.TimeStamp; //_store.CurrentKey.TimeStamp = now; //var ce2 = new CacheEntry(policy, GetCurrentDate(0)); //ce2.Value = value; //_store.CurrentValue = ce2; #endregion #endregion }); }
/// <summary> /// Retrievs cached entries given their Keys. If key is not found or expired, /// null will be returned to this item's Value portion of the KeyValuePair. /// </summary> /// <param name="keys"></param> /// <param name="regionName"></param> /// <returns></returns> public override IDictionary <string, object> GetValues(IEnumerable <string> keys, string regionName = null) { if (keys == null) { throw new ArgumentNullException("keys"); } var keysList = new List <CacheKey>(); foreach (var k in keys) { keysList.Add(new CacheKey(k)); } if (keysList.Count == 0) { return(new Dictionary <string, object>()); } Dictionary <string, object> r = new Dictionary <string, object>(keysList.Count); QueryResult <CacheKey>[] result = null; if (!_store.Locker.Invoke <bool>(() => { return(_store.Query(Sop.QueryExpression <CacheKey> .Package(keysList.ToArray()), out result)); })) { // just return, no need to update the TimeStamps as no match was found... return(r); } // package data Values onto the dictionary for return... //var l = new List<QueryResult<CacheKey>>(result.Length); //var now = GetCurrentDate(0); foreach (var res in result) { r[res.Key.Key] = res.Value; if (res.Found) { CacheEntry ce = res.Value as CacheEntry; if (!IsNotExpired(res.Key, ce, false)) { // try to update the expired entry... if (CacheEntrySetUpdateCallback != null) { CacheEntrySetUpdateCallback(new CacheEntryUpdateArguments[] { new CacheEntryUpdateArguments(this, CacheEntryRemovedReason.Expired, res.Key.Key, null) }); CacheEntry entry; var resKey = res.Key; _store.Locker.Invoke(() => { if (_store.TryGetValue(resKey, out entry)) { if (IsNotExpired(resKey, entry, false)) { r[resKey.Key] = _store.CurrentValue.Value; } } }); } } //else if (!ce.NonExpiring) // l.Add(res); } } return(r); }