Changeset 6291 for trunk/sources/HeuristicLab.Problems.ExternalEvaluation
- Timestamp:
- 05/25/11 17:22:58 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.3/EvaluationCache.cs
r6265 r6291 44 44 45 45 #region Types 46 private class CacheEntry {47 48 public string Key { get; private set; }49 public double Value { get; set; }46 private sealed class CacheEntry { 47 48 public readonly string Key; 49 public double Value; 50 50 51 51 public CacheEntry(string key, double value) { … … 54 54 } 55 55 56 public CacheEntry(string key) : this(key, 0) { } 56 public CacheEntry(string key) { 57 Key = key; 58 } 57 59 58 60 public override bool Equals(object obj) { … … 78 80 private LinkedList<CacheEntry> list; 79 81 private Dictionary<CacheEntry, LinkedListNode<CacheEntry>> index; 82 80 83 private HashSet<string> activeEvaluations = new HashSet<string>(); 81 private object cacheLock = new object(); 82 private object evaluationLock = new object(); 83 private AutoResetEvent evaluationDone = new AutoResetEvent(false); 84 private object cacheLock = new object(); 84 85 #endregion 85 86 … … 88 89 get { return VSImageLibrary.Database; } 89 90 } 90 public int Size { 91 get { 92 lock (cacheLock) { 93 return index.Count; 94 } 95 } 96 } 97 public int ActiveEvaluations { 98 get { 99 lock (evaluationLock) { 100 return activeEvaluations.Count; 101 } 102 } 103 } 91 public int Size { get { lock (cacheLock) return index.Count; } } 92 public int ActiveEvaluations { get { lock (cacheLock) return activeEvaluations.Count; } } 93 104 94 [Storable] 105 95 public int Hits { get; private set; } … … 107 97 108 98 #region events 109 public event EventHandler SizeChanged; 110 public event EventHandler HitsChanged; 111 public event EventHandler ActiveEvalutionsChanged; 112 113 protected virtual void OnSizeChanged() { 114 EventHandler handler = SizeChanged; 115 if (handler != null) 116 handler(this, EventArgs.Empty); 117 } 118 protected virtual void OnHitsChanged() { 119 EventHandler handler = HitsChanged; 120 if (handler != null) 121 handler(this, EventArgs.Empty); 122 } 123 protected virtual void OnActiveEvalutionsChanged() { 124 EventHandler handler = ActiveEvalutionsChanged; 99 public event EventHandler Changed; 100 101 protected virtual void OnChanged() { 102 EventHandler handler = Changed; 125 103 if (handler != null) 126 104 handler(this, EventArgs.Empty); … … 195 173 if (Capacity < 0) 196 174 throw new ArgumentOutOfRangeException("Cache capacity cannot be less than zero"); 197 Trim(); 175 lock (cacheLock) 176 Trim(); 177 OnChanged(); 198 178 } 199 179 #endregion … … 206 186 Hits = 0; 207 187 } 208 OnSizeChanged(); 209 OnHitsChanged(); 188 OnChanged(); 210 189 } 211 190 … … 214 193 LinkedListNode<CacheEntry> node; 215 194 bool lockTaken = false; 216 try { 195 bool waited = false; 196 try { 217 197 Monitor.Enter(cacheLock, ref lockTaken); 218 if (index.TryGetValue(entry, out node)) { 219 list.Remove(node); 220 list.AddLast(node); 221 Hits++; 222 lockTaken = false; 223 Monitor.Exit(cacheLock); 224 OnHitsChanged(); 225 return node.Value.Value; 226 } else { 227 lockTaken = false; 228 Monitor.Exit(cacheLock); 229 return Evaluate(message, evaluate, entry); 198 while (true) { 199 if (index.TryGetValue(entry, out node)) { 200 list.Remove(node); 201 list.AddLast(node); 202 Hits++; 203 lockTaken = false; 204 Monitor.Exit(cacheLock); 205 OnChanged(); 206 return node.Value.Value; 207 } else { 208 if (!waited && activeEvaluations.Contains(entry.Key)) { 209 while (activeEvaluations.Contains(entry.Key)) 210 Monitor.Wait(cacheLock); 211 waited = true; 212 } else { 213 activeEvaluations.Add(entry.Key); 214 lockTaken = false; 215 Monitor.Exit(cacheLock); 216 OnChanged(); 217 try { 218 entry.Value = evaluate(message); 219 Monitor.Enter(cacheLock, ref lockTaken); 220 index[entry] = list.AddLast(entry); 221 Trim(); 222 } finally { 223 if (!lockTaken) 224 Monitor.Enter(cacheLock, ref lockTaken); 225 activeEvaluations.Remove(entry.Key); 226 Monitor.PulseAll(cacheLock); 227 lockTaken = false; 228 Monitor.Exit(cacheLock); 229 } 230 OnChanged(); 231 return entry.Value; 232 } 233 } 230 234 } 231 235 } finally { … … 235 239 } 236 240 237 private double Evaluate(SolutionMessage message, Evaluator evaluate, CacheEntry entry) {238 bool lockTaken = false;239 try {240 Monitor.Enter(evaluationLock, ref lockTaken);241 if (activeEvaluations.Contains(entry.Key)) {242 while (activeEvaluations.Contains(entry.Key)) {243 lockTaken = false;244 Monitor.Exit(evaluationLock);245 evaluationDone.WaitOne();246 Monitor.Enter(evaluationLock, ref lockTaken);247 }248 lock (cacheLock) {249 return index[entry].Value.Value;250 }251 } else {252 activeEvaluations.Add(entry.Key);253 lockTaken = false;254 Monitor.Exit(evaluationLock);255 OnActiveEvalutionsChanged();256 try {257 entry.Value = evaluate(message);258 lock (cacheLock) {259 index[entry] = list.AddLast(entry);260 }261 Trim();262 } finally {263 lock (evaluationLock) {264 activeEvaluations.Remove(entry.Key);265 evaluationDone.Set();266 }267 OnActiveEvalutionsChanged();268 }269 return entry.Value;270 }271 } finally {272 if (lockTaken)273 Monitor.Exit(evaluationLock);274 }275 }276 277 241 private void Trim() { 278 lock (cacheLock) { 279 while (list.Count > Capacity) { 280 LinkedListNode<CacheEntry> item = list.First; 281 list.Remove(item); 282 index.Remove(item.Value); 283 } 284 } 285 OnSizeChanged(); 242 while (list.Count > Capacity) { 243 LinkedListNode<CacheEntry> item = list.First; 244 list.Remove(item); 245 index.Remove(item.Value); 246 } 286 247 } 287 248 … … 318 279 } 319 280 #endregion 320 } 281 } 321 282 }
Note: See TracChangeset
for help on using the changeset viewer.