public bool Add(T key, ICacheable cacheable) { lock (syncRoot) { if (cacheable == null) { throw new ArgumentNullException("cacheable"); } CachableData dummy; if (sorted.TryGetValue(key, out dummy)) { return(false); } // Cacheable was cached, must throw exception if already cached. cacheable.Cached(); // Create data. CachableData data = new CachableData(); data.Data = cacheable; data.Score = initialScore; data.EvalData = new object[evaluators.Length]; for (int i = 0; i < evaluators.Length; i++) { data.EvalData[i] = evaluators[i].Data; } // Add touched event. data.Data.OnTouch += new Action <ICacheable>(delegate(ICacheable unused) { lock (syncRoot) { // Perform the touch. for (int j = 0; j < evaluators.Length; j++) { data.Score = evaluators[j].Touch(data.EvalData[j], data.Score); } // Touching certainly ensures at least 0.0f value. data.Score = Math.MathHelper.Max(0.0f, data.Score); data.Score = Math.MathHelper.Min(maxScore, data.Score); } }); // Resource is created in touched state, no need to re-touch. This // method may throw if key already exists, but we already prechecked for uniquness. sorted.Add(key, data); return(true); } }
public uint Update() { lock (syncRoot) { List <T> toDelete = new List <T>(); DateTime nowTime = DateTime.Now; TimeSpan span = nowTime - this.lastUpdate; // We go through all. foreach (KeyValuePair <T, CachableData> pair in sorted) { CachableData c = pair.Value; for (int i = 0; i < evaluators.Length; i++) { c.Score = evaluators[i].Update(c.EvalData[i], span, c.Score); } if (c.Score < 0.0f) { toDelete.Add(pair.Key); c.Data.Dispose(); continue; } c.Score = Math.MathHelper.Min(maxScore, c.Score); } // We delete all keys. for (int i = 0; i < toDelete.Count; i++) { sorted.Remove(toDelete[i]); } lastUpdate = nowTime; return((uint)toDelete.Count); } }