public void RefreshShouldSetExpireDate() { var value = new CacheValue <string>("value", new TimeSpan(1, 0, 0)); value.Refresh(new TimeSpan(1, 0, 0)); Assert.Equal(DateTime.UtcNow.AddHours(1), value.ExpiredDateUtc, new TimeSpan(0, 0, 1)); }
public void ForMaxValueTimespanRefreshShouldSetMaxExpireDate() { var value = new CacheValue <string>("value", new TimeSpan(0, 0, 0)); value.Refresh(TimeSpan.MaxValue); Assert.Equal(DateTime.MaxValue, value.ExpiredDateUtc); }
private object AddAndGet(string cacheKey, object value, long version, TimeSpan?timeToLive) { _writeLock.Wait(); try { if (_version != version) { return(null); } var cacheValue = (CacheValue)_memoryCache.Get(cacheKey); if (cacheValue != null) { // The key was added in the meantime return(cacheValue.Value ?? value); } cacheValue = new CacheValue(value, version, new SemaphoreSlim(1, 1)); if (timeToLive.HasValue) { PutLocal(cacheKey, cacheValue, timeToLive.Value); } else { PutLocal(cacheKey, cacheValue); } } finally { _writeLock.Release(); } return(value); }
private async Task AddCacheAsync(Response response) { if (response == null) { throw new ArgumentNullException(nameof(response)); } if (response.Type == ResponseType.None) { return; } var chennelId = await response.Channel.GetIdAsync(); if (_cache.TryGetValue(chennelId, out var value)) { value.Responses.Add(response); } else { var responses = new List <Response> { response }; _cache[chennelId] = new CacheValue(response.Channel, responses); } }
public async Task GetCacheAsyncTestAsync() { var mockStorageAdapterClient = new Mock <IStorageAdapterClient>(); var cache = new Cache( mockStorageAdapterClient.Object, new Mock <IIothubManagerServiceClient>().Object, new Mock <ISimulationServiceClient>().Object, new ServicesConfig(), new Logger("UnitTest", LogLevel.Debug)); var cacheValue = new CacheValue { Rebuilding = false, Tags = new HashSet <string> { "c", "a", "y", "z" }, Reported = new HashSet <string> { "1", "9", "2", "3" } }; mockStorageAdapterClient .Setup(m => m.GetAsync(It.IsAny <string>(), It.IsAny <string>())) .Returns(() => Task.FromResult(new ValueApiModel { Data = JsonConvert.SerializeObject(cacheValue) })); var result = await cache.GetCacheAsync(); Assert.True(result.Tags.OrderBy(m => m).SequenceEqual(cacheValue.Tags.OrderBy(m => m))); Assert.True(result.Reported.OrderBy(m => m).SequenceEqual(cacheValue.Reported.OrderBy(m => m))); }
private async Task StartReceive(CancellationToken token) { EnumeratorResult <ChunkedStream> res; while ((res = await _client.ReceiveAsync(token)).Success) { using (res.Value) using (var reader = new MemoryStreamReader()) { var response = ProtoBuf.Serializer.Deserialize <ResponseMessageModel>(res.Value); var items = new CacheValue <Tk, T> [response.Messages.Count]; var idx = 0; foreach (var message in response.Messages) { reader.SetBuffer(message.Key); reader.SetLength(message.Key.Length); var key = ProtoBuf.Serializer.Deserialize <Tk>(reader); reader.SetBuffer(message.Value); reader.SetLength(message.Value.Length); var val = ProtoBuf.Serializer.Deserialize <T>(reader); items[idx++] = new CacheValue <Tk, T>(key, val, message.ExpiredAtSeconds); } _cache.AddRange(items); } } }
public override async Task <CacheValue <T> > BaseGetAsync <T>(string cacheKey, Func <Task <T> > dataRetriever, TimeSpan expiration) { CacheValue <T> cacheValue = _memoryProvider.Get <T>(cacheKey); if (cacheValue.IsNull) { cacheValue = _redisProvider.Get <T>(cacheKey); if (cacheValue.HasValue) { var expri = _redisProvider.GetExpiration(cacheKey); if (expri != TimeSpan.Zero) { _memoryProvider.Set(cacheKey, cacheValue.Value, expri); } } } if (cacheValue.IsNull) { T data = await dataRetriever(); if (data != null) { _memoryProvider.Set <T>(cacheKey, data, expiration); _redisProvider.Set <T>(cacheKey, data, expiration); cacheValue = new CacheValue <T>(data, true); } } return(cacheValue); }
private State DoParse(State state, List <Result> results, string nonterminal) { State start = state; CacheValue cache; CacheKey key = new CacheKey(nonterminal, start.Index); if (!m_cache.TryGetValue(key, out cache)) { ParseMethod[] methods = m_nonterminals[nonterminal]; int oldCount = results.Count; state = DoChoice(state, results, methods); bool hasResult = state.Parsed && results.Count > oldCount; string value = hasResult ? results[results.Count - 1].Value : default(string); cache = new CacheValue(state, value, hasResult); m_cache.Add(key, cache); } else { if (cache.HasResult) { results.Add(new Result(this, start.Index, cache.State.Index - start.Index, m_input, cache.Value)); } } return(cache.State); }
public void NoValue_CacheValue_Should_Succeed() { CacheValue <string> value = CacheValue <string> .NoValue; Assert.False(value.HasValue); Assert.Equal(default(string), value.Value); }
public void Create_CacheValue_Should_Succeed() { CacheValue <string> value = new CacheValue <string>("value", true); Assert.True(value.HasValue); Assert.Equal("value", value.Value); }
private CacheResult <ICacheItem <TVal> > DeserializeCacheItem <TVal>(CacheValue cacheValue, string partition, string key) { if (cacheValue == null || cacheValue.Value == null) { // Nothing to deserialize, return None. return(default(CacheResult <ICacheItem <TVal> >)); } try { // Generate the KVLite cache item and return it. Many properties available in the // KVLite cache items cannot be filled due to missing information. return(new CacheItem <TVal> { Partition = partition, Key = key, Value = UnsafeDeserializeCacheValue <TVal>(cacheValue), UtcCreation = cacheValue.UtcCreation }); } catch (Exception ex) { LastError = ex; Log.WarnException(ErrorMessages.InternalErrorOnDeserialization, ex, partition, key, Settings.CacheName); return(default(CacheResult <ICacheItem <TVal> >)); } }
/// <summary> /// 获取缓存 /// </summary> /// <typeparam name="T">数据类型</typeparam> /// <param name="cacheKey">缓存键</param> /// <param name="dataRetriever">数据检索器</param> /// <param name="expiry">过期时间</param> /// <returns></returns> public async Task <CacheValue <T> > GetAsync <T>(string cacheKey, Func <Task <T> > dataRetriever, TimeSpan expiry) where T : class { Check.NotNullOrEmpty(cacheKey, nameof(cacheKey)); Check.NotNegativeOrZero(expiry, nameof(expiry)); CacheValue <T> cachedValue = null; foreach (var provider in _providers) { cachedValue = await provider.GetAsync(cacheKey, dataRetriever, expiry); if (cachedValue.HasValue) { break; } } if (!cachedValue.HasValue) { var retriever = await dataRetriever?.Invoke(); if (retriever != null) { await SetAsync(cacheKey, retriever, expiry); return(new CacheValue <T>(retriever, true)); } return(CacheValue <T> .NoValue); } return(cachedValue); }
public void Add_Should_Replace_MRU_Item_When_Cache_Is_Full_And_MRU_Is_The_Replacement_Handler() { var mruCache = new SetAssociativeCache <CacheKey, CacheValue>(numberOfWays, numberOfSets, () => new MRUReplacementHandler <CacheKey, CacheValue>()); // Arrange int setIndex = 1; var cacheKeys = FillCacheSet(setIndex, cache); VisitCacheItems(new List <CacheKey>() { cacheKeys.First() }, mruCache); var mostRecentlyUsedKey = cacheKeys.First(); // Act var empNumber = new CacheKey("001", setIndex); var empName = new CacheValue("Steve Jobs"); cache.Add(empNumber, empName); // Assert cache.Contains(mostRecentlyUsedKey).Should().BeFalse(); cache.Get(empNumber).Should().Be(empName); }
/// <summary> /// Get the specified cacheKey, dataRetriever and expiration. /// </summary> /// <returns>The get.</returns> /// <param name="cacheKey">Cache key.</param> /// <param name="dataRetriever">Data retriever.</param> /// <param name="expiration">Expiration.</param> /// <typeparam name="T">The 1st type parameter.</typeparam> public CacheValue <T> Get <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration)); CacheValue <T> cachedValue = null; foreach (var provider in _providers) { cachedValue = provider.Get(cacheKey, dataRetriever, expiration); if (cachedValue.HasValue) { break; } } if (!cachedValue.HasValue) { var retriever = dataRetriever(); if (retriever != null) { Set(cacheKey, retriever, expiration); return(new CacheValue <T>(retriever, true)); } else { //TODO : Set a null value to cache!! return(CacheValue <T> .NoValue); } } return(cachedValue); }
protected override void SetValue(object key, CacheValue value, string policyName = null) { var entry = (cache as IMemoryCache).CreateEntry(key); entry.SetValue(value); entry.Dispose(); }
public static CacheItem <CacheKey, CacheValue> BuildCacheItem(string strKey, string strValue) { var key = new CacheKey(strKey); var value = new CacheValue(strValue); return(new CacheItem <CacheKey, CacheValue>(key, value)); }
protected override bool GetValue(object key, out CacheValue value) { var _value = (cache as IMemoryCache).Get(key); value = (cache as IMemoryCache).Get(key) as CacheValue; return(value != null); }
/// <summary> /// Gets the specified cacheKey, dataRetriever and expiration async. /// </summary> /// <returns>The async.</returns> /// <param name="cacheKey">Cache key.</param> /// <param name="dataRetriever">Data retriever.</param> /// <param name="expiration">Expiration.</param> /// <typeparam name="T">The 1st type parameter.</typeparam> public async Task <CacheValue <T> > GetAsync <T>(string cacheKey, Func <Task <T> > dataRetriever, TimeSpan expiration) { ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey)); ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration)); CacheValue <T> cachedValue = null; foreach (var provider in _providers) { cachedValue = provider.Get <T>(cacheKey); if (cachedValue.HasValue) { break; } } if (!cachedValue.HasValue) { var retriever = await dataRetriever?.Invoke(); if (retriever != null) { await SetAsync(cacheKey, retriever, expiration); return(new CacheValue <T>(retriever, true)); } else { return(CacheValue <T> .NoValue); } } return(cachedValue); }
/// <summary> /// Return the value for the specified key. /// if the cache not contains value, it is initialized with the return of fetcher method /// </summary> /// <param name="key">The key is the cache key</param> /// <param name="fetcher">The fetcher.</param> /// <returns>cache value</returns> public object GetOrResolve(object key, Func <object> fetcher, string policyName = null) { CacheValue value; if (!GetValue(key, out value)) { // scale locks objects on x items for best locking performance. // Resolve lock index to use. int hashcode = key.GetHashCode(); int lockNo = (hashcode & 0x7fffffff) % _concurrencyLevel; Debug.Assert(lockNo >= 0 && lockNo < _concurrencyLevel); var l = this._locks[lockNo]; lock (l._syncLock) { if (!GetValue(key, out value)) { SetValue(key, (value = new CacheValue()), policyName); } } } object result = value.GetValue(fetcher); return(result); }
public override CacheValue <T> BaseGet <T>(string cacheKey, Func <T> dataRetriever, TimeSpan expiration) { CacheValue <T> cacheValue = _memoryProvider.Get <T>(cacheKey); if (cacheValue.IsNull) { cacheValue = _redisProvider.Get <T>(cacheKey); if (cacheValue.HasValue) { var expration = _redisProvider.GetExpiration(cacheKey); if (expration != null && expration != TimeSpan.Zero) { _memoryProvider.Set <T>(cacheKey, cacheValue.Value, expration); } } } if (cacheValue.HasValue) { return(cacheValue); } T data = dataRetriever(); if (data != null) { _memoryProvider.Set <T>(cacheKey, data, expiration); _redisProvider.Set <T>(cacheKey, data, expiration); return(new CacheValue <T>(data, true)); } return(new CacheValue <T>(data, false)); }
public void Null_CacheValue_Should_Succeed() { CacheValue <string> value = CacheValue <string> .Null; Assert.True(value.HasValue); Assert.Equal(default(string), value.Value); }
protected override void UpdateElementAccess(object key, CacheValue cacheValue) { base.UpdateElementAccess(key, cacheValue); while (IndexList.Count > MaxSize) { RemoveUnlocked(IndexList.Last.Value.Key); } }
//> DoNAssert //< DoParse private State DoParse(State state, List <Result> results, int nonterminal) { int startIndex = state.Index; CacheValue cache; long key = CacheValue.CalcKey(nonterminal, startIndex); if (!m_cache.TryGetValue(key, out cache)) { if (nonterminal < 0 || nonterminal >= (int)NonTerminalEnum.NonTerminalNum) { throw new Exception("Couldn't find a " + nonterminal + " parse method"); } ParseMethod[] methods = m_nonterminals[(int)nonterminal]; int oldCount = null == results ? 0 : results.Count; // {{value != 'void'}} state = DoChoice(state, results, methods); bool hasResult = state.Parsed && null != results && results.Count > oldCount; // {{value != 'void'}} VALUE value = hasResult ? results[results.Count - 1].Value : default(VALUE); // {{value != 'void'}} cache = new CacheValue(ref state, ref value, hasResult); // {{value != 'void'}} cache = new CacheValue(ref state, state.Parsed); // {{value == 'void'}} m_cache.Add(key, cache); } else { Console.WriteLine(nonterminal); // {{debug != 'none'}} if (cache.HasResult && null != results) { results.Add(new Result(this, startIndex, cache.State.Index - startIndex, m_input, cache.Value)); // {{value == 'XmlNode'}} } results.Add(new Result(this, startIndex, cache.State.Index - startIndex, m_input, ref cache.Value)); // {{value != 'void' and value != 'XmlNode'}} results.Add(new Result(this, startIndex, cache.State.Index - startIndex, m_input)); // {{value == 'void'}} string name = string.Format("cached '{0}' ", nonterminal); // {{debug != 'none'}} if (m_file == m_debugFile) // {{debugging and has-debug-file}} { // {{debugging and has-debug-file}} if (cache.State.Parsed) // {{(debug == 'matches' or debug == 'both') and has-debug-file}} { DoDebugMatch(startIndex, cache.State.Index, name + "parsed"); // {{(debug == 'matches' or debug == 'both') and has-debug-file}} } if (!cache.State.Parsed) // {{(debug == 'failures' or debug == 'both') and has-debug-file}} { DoDebugFailure(startIndex, name + DoEscapeAll(cache.State.Errors.ToString())); // {{(debug == 'failures' or debug == 'both') and has-debug-file}} } } // {{debugging and has-debug-file}} if (cache.State.Parsed) // {{(debug == 'matches' or debug == 'both') and not has-debug-file}} { DoDebugMatch(startIndex, cache.State.Index, name + "parsed"); // {{(debug == 'matches' or debug == 'both') and not has-debug-file}} } if (!cache.State.Parsed) // {{(debug == 'failures' or debug == 'both') and not has-debug-file}} { DoDebugFailure(startIndex, name + DoEscapeAll(cache.State.Errors.ToString())); // {{(debug == 'failures' or debug == 'both') and not has-debug-file}} } } return(cache.State); }
public Hashtable GenerateHash(EnumUtil.CacheTypes CacheType, EnumUtil.CachePeriods CachePeriod, string CacheDescription, DataTable dtDataSource, string SplitCellName) { Hashtable Hash = new Hashtable(); DataTable dtData = new DataTable(); string Key = String.Empty; CacheValue CacheValue = new CacheValue(); if (SplitCellName == String.Empty) { SplitCellName = this.SplitCellName; } if (isHasSplitCell(dtDataSource, SplitCellName)) { dtDataSource.DefaultView.Sort = SplitCellName; dtDataSource = dtDataSource.DefaultView.ToTable(); for (int i = 0; i < dtDataSource.Rows.Count; i++) { if (i != dtDataSource.Rows.Count - 1) { if (dtDataSource.Rows[i][SplitCellName].ToString() == dtDataSource.Rows[i + 1][SplitCellName].ToString()) { if (dtData.Columns.Count < 1) { dtData = dtDataSource.Clone(); } dtData.Rows.Add(dtDataSource.Rows[i].ItemArray); } else { dtData.Rows.Add(dtDataSource.Rows[i].ItemArray); Key = ReturnStrKey(CacheType, Convert.ToInt32(dtDataSource.Rows[i][SplitCellName])); CacheValue = SetCacheData(CacheType, CachePeriod, CacheDescription, dtData); Hash.Add(Key, CacheValue); dtData = new DataTable(); } } else { if (dtData.Columns.Count < 1) { dtData = dtDataSource.Clone(); } dtData.Rows.Add(dtDataSource.Rows[i].ItemArray); Key = ReturnStrKey(CacheType, Convert.ToInt32(dtDataSource.Rows[i][SplitCellName])); CacheValue = SetCacheData(CacheType, CachePeriod, CacheDescription, dtData); Hash.Add(Key, CacheValue); dtData = new DataTable(); } } } else { Key = ReturnStrKey(CacheType, 0); CacheValue = SetCacheData(CacheType, CachePeriod, CacheDescription, dtDataSource); Hash.Add(Key, CacheValue); } return(Hash); }
public void AddToCache(uint hash, int[] values) { if (Cache.ContainsKey(hash)) { TotalValues -= Math.Max(0, TotalValues - Cache[hash].Value.Length); } Cache[hash] = new CacheValue<int[]>(values); TotalValues += values.Length; }
public Table(By locator) : base(locator) { TableHeadersLocator = By.XPath(".//tr/th"); TableBodyLocator = By.XPath(".//tbody"); TableFooterLocator = By.XPath(".//tfoot"); TableRowsLocator = By.XPath(".//tr"); TableCellsLocator = By.XPath(".//td"); _row = new CacheValue <Line>(() => Row(1)); }
public void IsExpire() { var value = new CacheValue <string>("value", new TimeSpan(0, 0, 0)); Assert.True(value.IsExpire); value = new CacheValue <string>("value", new TimeSpan(0, 1, 0)); Assert.False(value.IsExpire); }
public async Task <CacheValue> SetCacheAsync(CacheValue cache) { // To simplify code, use empty set to replace null set cache.Tags = cache.Tags ?? new HashSet <string>(); cache.Reported = cache.Reported ?? new HashSet <string>(); string etag = null; while (true) { ValueApiModel model = null; try { model = await this.storageClient.GetAsync(CACHE_COLLECTION_ID, CACHE_KEY); } catch (ResourceNotFoundException) { this.log.Info($"Cache updating: cache {CACHE_COLLECTION_ID}:{CACHE_KEY} was not found", () => { }); } if (model != null) { CacheValue cacheServer; try { cacheServer = JsonConvert.DeserializeObject <CacheValue>(model.Data); } catch { cacheServer = new CacheValue(); } cacheServer.Tags = cacheServer.Tags ?? new HashSet <string>(); cacheServer.Reported = cacheServer.Reported ?? new HashSet <string>(); cache.Tags.UnionWith(cacheServer.Tags); cache.Reported.UnionWith(cacheServer.Reported); etag = model.ETag; if (cache.Tags.Count == cacheServer.Tags.Count && cache.Reported.Count == cacheServer.Reported.Count) { return(cache); } } var value = JsonConvert.SerializeObject(cache); try { var response = await this.storageClient.UpdateAsync(CACHE_COLLECTION_ID, CACHE_KEY, value, etag); return(JsonConvert.DeserializeObject <CacheValue>(response.Data)); } catch (ConflictingResourceException) { this.log.Info("Cache updating: failed due to conflict. Retry soon", () => { }); } } }
public void Add(E e, T t, DateTime date, DateTime expires) { if (map.ContainsKey(e)) { return; } CacheValue <T> value = new CacheValue <T>(t, date, expires); map.Add(e, value); }
protected virtual async Task <T> Get <T>(string key) { CacheValue <WrappedObject <T> > cache = await _cache.GetAsync <WrappedObject <T> >(key).ConfigureAwait(false); if (cache.HasValue) { return(await UnWrap(cache.Value)); } return(default);
/// <summary> /// 同步方式获取或添加缓存 /// </summary> /// <param name="key">缓存唯一Key</param> /// <param name="data">缓存内容</param> /// <param name="timeSpan"></param> public void AddOrUpdate(string key, T data) { using (asyncRoot.Lock()) { var value = new CacheValue { Value = data }; this.memoryCaches.Set(key, value, this.GetDateTimeOffset()); } }
public bool Set(CacheKey key, CacheValue value) { if (this.logger != null) { this.logger.Log("Set " + key.ToString() + ":" + value.ToString(), Category.Info, Priority.Medium); } if (this.Remove(key) == false) { return false; } return this.mediums[0].Set(key, value); }
public override void OnActionExecuted(HttpActionExecutedContext ac) { if (!IsCacheable(ac.Request.Method) || ac.Exception != null) { return; } var cachekey = CreateCacheKey(ac.Request); var cache = GetCache(); if (cache.Get(cachekey) == null) { var value = new CacheValue { ContentType = ac.Response.Content.Headers.ContentType.MediaType, Charset = ac.Response.Content.Headers.ContentType.CharSet, Result = ac.Response.Content.ReadAsStringAsync().Result }; var evictionPolicy = CreateCacheEvictionPolicy(); cache.Insert(cachekey, value, evictionPolicy); } }
public GetCacheItemEventArgs(CacheKey key, CacheValue value) : base() { this.key = key; this.value = value; }
private void MoveCacheItem(ICacheMedium from, ICacheMedium to, CacheKey key, CacheValue value) { if (this.logger != null) { this.logger.Log("Move cache item: " + key.ToString() + " from " + from.CacheName + " to " + to.CacheName, Category.Info, Priority.Medium); } from.Remove(key); to.Set(key, value); }
void LoadContent() { AbstractBufferedReader reader; foreach (var collectionFile in _fileCollection.Enumerate()) { reader = collectionFile.GetExclusiveReader(); if (!reader.CheckMagic(MagicStartOfFile)) continue; // Don't touch files alien files var fileType = (DiskChunkFileType)reader.ReadUInt8(); IFileInfo fileInfo; switch (fileType) { case DiskChunkFileType.HashIndex: fileInfo = new FileHashIndex(reader); break; case DiskChunkFileType.PureValues: fileInfo = new FilePureValues(reader); break; default: fileInfo = UnknownFile.Instance; break; } if (_fileGeneration < fileInfo.Generation) _fileGeneration = fileInfo.Generation; _fileInfos.TryAdd(collectionFile.Index, fileInfo); } var hashFilePair = _fileInfos.Where(f => f.Value.FileType == DiskChunkFileType.HashIndex).OrderByDescending( f => f.Value.Generation).FirstOrDefault(); if (hashFilePair.Value == null) return; reader = _fileCollection.GetFile(hashFilePair.Key).GetExclusiveReader(); FileHashIndex.SkipHeader(reader); if (((FileHashIndex)hashFilePair.Value).KeySize != _keySize) return; var keyBuf = ByteBuffer.NewSync(new byte[_keySize]); while (true) { var cacheValue = new CacheValue(); cacheValue.FileOfs = reader.ReadVUInt32(); if (cacheValue.FileOfs == 0) break; cacheValue.FileId = reader.ReadVUInt32(); cacheValue.AccessRate = reader.ReadVUInt32(); cacheValue.ContentLength = reader.ReadVUInt32(); reader.ReadBlock(keyBuf); _cache.TryAdd(new ByteStructs.Key20(keyBuf), cacheValue); } }
public bool Set(CacheKey key, CacheValue value) { return this.Set(new CacheItem[] { new CacheItem(key, value) }); }
protected virtual CacheValue SetValueUnlocked(object key, object value) { lastCacheAccess = DateTime.Now; var cacheValue = GetCacheValueUnlocked(key); if (cacheValue == null) { cacheValue = new CacheValue(value); cacheValue.IsNew = true; valueCache[key] = cacheValue; } else { cacheValue.Value = value; cacheValue.IsNew = false; } UpdateElementAccess(key, cacheValue); return cacheValue; }
protected virtual void UpdateElementAccess(object key, CacheValue cacheValue) { // update last access and move it to the head of the list cacheValue.LastAccess = DateTime.Now; var idxRef = cacheValue.IndexRef; if (idxRef != null) { IndexList.Remove(idxRef); } else { idxRef = new LinkedListNode<KeyValuePair<object, CacheValue>>(new KeyValuePair<object, CacheValue>(key, cacheValue)); cacheValue.IndexRef = idxRef; } IndexList.AddFirst(idxRef); }