/// <summary> /// Gets an object from the cache or creates it if it doesnt exist /// </summary> /// <param name="key">key to item</param> /// <param name="expire">Expire this item after this much time. -1 for NEVER</param> /// <param name="f">Factory method if key doesnt exist</param> /// <returns></returns> public object Get(string key, TimeSpan expire, Func <object> f) { CacheItem item = backend.Get(key); if (item == null) { if (f != null) { object val = f(); item = new CacheItem(key, val); // anything less than 0 is NEVER if (expire.Ticks < 0) { item.Stats.Expire = DateTime.MaxValue; } else { item.Stats.Expire = item.Stats.Created + expire; } backend.Set(item); } } if (item == null) { return(null); } // item is expired.. if (item.Stats.Expire <= DateTime.Now) { // recreate it.. if (f != null) { object val = f(); item = new CacheItem(key, val); backend.Set(item); } } // anything less than 0 is NEVER if (expire.Ticks < 0) { item.Stats.Expire = DateTime.MaxValue; } else { item.Stats.Expire = item.Stats.Created + expire; } // update access statistics for the item backend.Touch(item); return(item.Value); }
/// <summary> /// Prune old entries from the cache /// </summary> protected void Prune() { if (Full == false) { return; } // ascending order (ie, oldest first) var tmp = data.OrderBy(x => x.Value.Stats.LastAccessTime); foreach (KeyValuePair <string, CacheItem> c in tmp) { CacheItem ci = Remove(c.Key); if (fallback != null) { fallback.Set(ci); } // dont need to remove any more if (Full == false) { break; } } }
public CacheItem Remove(string key) { // TODO: get the cacheItem first.. FileEntry e; CacheItem ret = null; pruneLock.EnterWriteLock(); try { if (data.TryGetValue(key, out e)) { Console.WriteLine("Removing " + key); ret = Deserialize(e); data.Remove(key); // place expired item into the fallback, // if we have one if (this.fallback != null) { fallback.Set(ret); } } } finally { pruneLock.ExitWriteLock(); } if (e != null) { MarkFreeSpace(e.Segment); } return(ret); }