diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/Cache.cs | 920 |
1 files changed, 460 insertions, 460 deletions
diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs index 88b86a3..780e262 100644 --- a/OpenSim/Framework/Cache.cs +++ b/OpenSim/Framework/Cache.cs | |||
@@ -4,464 +4,464 @@ using libsecondlife; | |||
4 | 4 | ||
5 | namespace Opensim.Framework | 5 | namespace Opensim.Framework |
6 | { | 6 | { |
7 | // The delegate we will use for performing fetch from backing store | 7 | // The delegate we will use for performing fetch from backing store |
8 | // | 8 | // |
9 | public delegate Object FetchDelegate(LLUUID index); | 9 | public delegate Object FetchDelegate(LLUUID index); |
10 | public delegate bool ExpireDelegate(LLUUID index); | 10 | public delegate bool ExpireDelegate(LLUUID index); |
11 | 11 | ||
12 | // Strategy | 12 | // Strategy |
13 | // | 13 | // |
14 | // Conservative = Minimize memory. Expire items quickly. | 14 | // Conservative = Minimize memory. Expire items quickly. |
15 | // Balanced = Expire items with few hits quickly. | 15 | // Balanced = Expire items with few hits quickly. |
16 | // Aggressive = Keep cache full. Expire only when over 90% and adding | 16 | // Aggressive = Keep cache full. Expire only when over 90% and adding |
17 | // | 17 | // |
18 | public enum CacheStrategy | 18 | public enum CacheStrategy |
19 | { | 19 | { |
20 | Conservative = 0, | 20 | Conservative = 0, |
21 | Balanced = 1, | 21 | Balanced = 1, |
22 | Aggressive = 2 | 22 | Aggressive = 2 |
23 | } | 23 | } |
24 | 24 | ||
25 | // Select classes to store data on different media | 25 | // Select classes to store data on different media |
26 | // | 26 | // |
27 | public enum CacheMedium | 27 | public enum CacheMedium |
28 | { | 28 | { |
29 | Memory = 0, | 29 | Memory = 0, |
30 | File = 1 | 30 | File = 1 |
31 | } | 31 | } |
32 | 32 | ||
33 | public enum CacheFlags | 33 | public enum CacheFlags |
34 | { | 34 | { |
35 | CacheMissing = 1, | 35 | CacheMissing = 1, |
36 | AllowUpdate = 2 | 36 | AllowUpdate = 2 |
37 | } | 37 | } |
38 | 38 | ||
39 | // The base class of all cache objects. Implements comparison and sorting | 39 | // The base class of all cache objects. Implements comparison and sorting |
40 | // by the LLUUID member. | 40 | // by the LLUUID member. |
41 | // | 41 | // |
42 | // This is not abstract because we need to instantiate it briefly as a | 42 | // This is not abstract because we need to instantiate it briefly as a |
43 | // method parameter | 43 | // method parameter |
44 | // | 44 | // |
45 | public class CacheItemBase : IEquatable<CacheItemBase>, IComparable<CacheItemBase> | 45 | public class CacheItemBase : IEquatable<CacheItemBase>, IComparable<CacheItemBase> |
46 | { | 46 | { |
47 | public LLUUID uuid; | 47 | public LLUUID uuid; |
48 | public DateTime entered; | 48 | public DateTime entered; |
49 | public DateTime lastUsed; | 49 | public DateTime lastUsed; |
50 | public DateTime expires = new DateTime(0); | 50 | public DateTime expires = new DateTime(0); |
51 | public int hits = 0; | 51 | public int hits = 0; |
52 | 52 | ||
53 | public virtual Object Retrieve() | 53 | public virtual Object Retrieve() |
54 | { | 54 | { |
55 | return null; | 55 | return null; |
56 | } | 56 | } |
57 | 57 | ||
58 | public virtual void Store(Object data) | 58 | public virtual void Store(Object data) |
59 | { | 59 | { |
60 | } | 60 | } |
61 | 61 | ||
62 | public CacheItemBase(LLUUID index) | 62 | public CacheItemBase(LLUUID index) |
63 | { | 63 | { |
64 | uuid = index; | 64 | uuid = index; |
65 | entered = DateTime.Now; | 65 | entered = DateTime.Now; |
66 | lastUsed = entered; | 66 | lastUsed = entered; |
67 | } | 67 | } |
68 | 68 | ||
69 | public CacheItemBase(LLUUID index, DateTime ttl) | 69 | public CacheItemBase(LLUUID index, DateTime ttl) |
70 | { | 70 | { |
71 | uuid = index; | 71 | uuid = index; |
72 | entered = DateTime.Now; | 72 | entered = DateTime.Now; |
73 | lastUsed = entered; | 73 | lastUsed = entered; |
74 | expires = ttl; | 74 | expires = ttl; |
75 | } | 75 | } |
76 | 76 | ||
77 | public virtual bool Equals(CacheItemBase item) | 77 | public virtual bool Equals(CacheItemBase item) |
78 | { | 78 | { |
79 | return uuid == item.uuid; | 79 | return uuid == item.uuid; |
80 | } | 80 | } |
81 | 81 | ||
82 | public virtual int CompareTo(CacheItemBase item) | 82 | public virtual int CompareTo(CacheItemBase item) |
83 | { | 83 | { |
84 | return uuid.CompareTo(item.uuid); | 84 | return uuid.CompareTo(item.uuid); |
85 | } | 85 | } |
86 | 86 | ||
87 | public virtual bool IsLocked() | 87 | public virtual bool IsLocked() |
88 | { | 88 | { |
89 | return false; | 89 | return false; |
90 | } | 90 | } |
91 | } | 91 | } |
92 | 92 | ||
93 | // Simple in-memory storage. Boxes the object and stores it in a variable | 93 | // Simple in-memory storage. Boxes the object and stores it in a variable |
94 | // | 94 | // |
95 | public class MemoryCacheItem : CacheItemBase | 95 | public class MemoryCacheItem : CacheItemBase |
96 | { | 96 | { |
97 | private Object m_Data; | 97 | private Object m_Data; |
98 | 98 | ||
99 | public MemoryCacheItem(LLUUID index) : | 99 | public MemoryCacheItem(LLUUID index) : |
100 | base(index) | 100 | base(index) |
101 | { | 101 | { |
102 | } | 102 | } |
103 | 103 | ||
104 | public MemoryCacheItem(LLUUID index, DateTime ttl) : | 104 | public MemoryCacheItem(LLUUID index, DateTime ttl) : |
105 | base(index, ttl) | 105 | base(index, ttl) |
106 | { | 106 | { |
107 | } | 107 | } |
108 | 108 | ||
109 | public MemoryCacheItem(LLUUID index, Object data) : | 109 | public MemoryCacheItem(LLUUID index, Object data) : |
110 | base(index) | 110 | base(index) |
111 | { | 111 | { |
112 | Store(data); | 112 | Store(data); |
113 | } | 113 | } |
114 | 114 | ||
115 | public MemoryCacheItem(LLUUID index, DateTime ttl, Object data) : | 115 | public MemoryCacheItem(LLUUID index, DateTime ttl, Object data) : |
116 | base(index, ttl) | 116 | base(index, ttl) |
117 | { | 117 | { |
118 | Store(data); | 118 | Store(data); |
119 | } | 119 | } |
120 | 120 | ||
121 | public override Object Retrieve() | 121 | public override Object Retrieve() |
122 | { | 122 | { |
123 | return m_Data; | 123 | return m_Data; |
124 | } | 124 | } |
125 | 125 | ||
126 | public override void Store(Object data) | 126 | public override void Store(Object data) |
127 | { | 127 | { |
128 | m_Data = data; | 128 | m_Data = data; |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | // Simple persistent file storage | 132 | // Simple persistent file storage |
133 | // | 133 | // |
134 | public class FileCacheItem : CacheItemBase | 134 | public class FileCacheItem : CacheItemBase |
135 | { | 135 | { |
136 | public FileCacheItem(LLUUID index) : | 136 | public FileCacheItem(LLUUID index) : |
137 | base(index) | 137 | base(index) |
138 | { | 138 | { |
139 | } | 139 | } |
140 | 140 | ||
141 | public FileCacheItem(LLUUID index, DateTime ttl) : | 141 | public FileCacheItem(LLUUID index, DateTime ttl) : |
142 | base(index, ttl) | 142 | base(index, ttl) |
143 | { | 143 | { |
144 | } | 144 | } |
145 | 145 | ||
146 | public FileCacheItem(LLUUID index, Object data) : | 146 | public FileCacheItem(LLUUID index, Object data) : |
147 | base(index) | 147 | base(index) |
148 | { | 148 | { |
149 | Store(data); | 149 | Store(data); |
150 | } | 150 | } |
151 | 151 | ||
152 | public FileCacheItem(LLUUID index, DateTime ttl, Object data) : | 152 | public FileCacheItem(LLUUID index, DateTime ttl, Object data) : |
153 | base(index, ttl) | 153 | base(index, ttl) |
154 | { | 154 | { |
155 | Store(data); | 155 | Store(data); |
156 | } | 156 | } |
157 | 157 | ||
158 | public override Object Retrieve() | 158 | public override Object Retrieve() |
159 | { | 159 | { |
160 | //TODO: Add file access code | 160 | //TODO: Add file access code |
161 | return null; | 161 | return null; |
162 | } | 162 | } |
163 | 163 | ||
164 | public override void Store(Object data) | 164 | public override void Store(Object data) |
165 | { | 165 | { |
166 | //TODO: Add file access code | 166 | //TODO: Add file access code |
167 | } | 167 | } |
168 | } | 168 | } |
169 | 169 | ||
170 | // The main cache class. This is the class you instantiate to create | 170 | // The main cache class. This is the class you instantiate to create |
171 | // a cache | 171 | // a cache |
172 | // | 172 | // |
173 | public class Cache | 173 | public class Cache |
174 | { | 174 | { |
175 | private List<CacheItemBase> m_Index = new List<CacheItemBase>(); | 175 | private List<CacheItemBase> m_Index = new List<CacheItemBase>(); |
176 | 176 | ||
177 | private CacheStrategy m_Strategy; | 177 | private CacheStrategy m_Strategy; |
178 | private CacheMedium m_Medium; | 178 | private CacheMedium m_Medium; |
179 | private CacheFlags m_Flags = 0; | 179 | private CacheFlags m_Flags = 0; |
180 | private int m_Size = 1024; | 180 | private int m_Size = 1024; |
181 | private TimeSpan m_DefaultTTL = new TimeSpan(0); | 181 | private TimeSpan m_DefaultTTL = new TimeSpan(0); |
182 | public ExpireDelegate OnExpire; | 182 | public ExpireDelegate OnExpire; |
183 | 183 | ||
184 | // Comparison interfaces | 184 | // Comparison interfaces |
185 | // | 185 | // |
186 | private class SortLRU : IComparer<CacheItemBase> | 186 | private class SortLRU : IComparer<CacheItemBase> |
187 | { | 187 | { |
188 | public int Compare(CacheItemBase a, CacheItemBase b) | 188 | public int Compare(CacheItemBase a, CacheItemBase b) |
189 | { | 189 | { |
190 | if(a == null && b == null) | 190 | if (a == null && b == null) |
191 | return 0; | 191 | return 0; |
192 | if(a == null) | 192 | if (a == null) |
193 | return -1; | 193 | return -1; |
194 | if(b == null) | 194 | if (b == null) |
195 | return 1; | 195 | return 1; |
196 | 196 | ||
197 | return(a.lastUsed.CompareTo(b.lastUsed)); | 197 | return(a.lastUsed.CompareTo(b.lastUsed)); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | 200 | ||
201 | // Convenience constructors | 201 | // Convenience constructors |
202 | // | 202 | // |
203 | public Cache() | 203 | public Cache() |
204 | { | 204 | { |
205 | m_Strategy = CacheStrategy.Balanced; | 205 | m_Strategy = CacheStrategy.Balanced; |
206 | m_Medium = CacheMedium.Memory; | 206 | m_Medium = CacheMedium.Memory; |
207 | m_Flags = 0; | 207 | m_Flags = 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | public Cache(CacheMedium medium) : | 210 | public Cache(CacheMedium medium) : |
211 | this(medium, CacheStrategy.Balanced) | 211 | this(medium, CacheStrategy.Balanced) |
212 | { | 212 | { |
213 | } | 213 | } |
214 | 214 | ||
215 | public Cache(CacheMedium medium, CacheFlags flags) : | 215 | public Cache(CacheMedium medium, CacheFlags flags) : |
216 | this(medium, CacheStrategy.Balanced, flags) | 216 | this(medium, CacheStrategy.Balanced, flags) |
217 | { | 217 | { |
218 | } | 218 | } |
219 | 219 | ||
220 | public Cache(CacheMedium medium, CacheStrategy strategy) : | 220 | public Cache(CacheMedium medium, CacheStrategy strategy) : |
221 | this(medium, strategy, 0) | 221 | this(medium, strategy, 0) |
222 | { | 222 | { |
223 | } | 223 | } |
224 | 224 | ||
225 | public Cache(CacheStrategy strategy, CacheFlags flags) : | 225 | public Cache(CacheStrategy strategy, CacheFlags flags) : |
226 | this(CacheMedium.Memory, strategy, flags) | 226 | this(CacheMedium.Memory, strategy, flags) |
227 | { | 227 | { |
228 | } | 228 | } |
229 | 229 | ||
230 | public Cache(CacheFlags flags) : | 230 | public Cache(CacheFlags flags) : |
231 | this(CacheMedium.Memory, CacheStrategy.Balanced, flags) | 231 | this(CacheMedium.Memory, CacheStrategy.Balanced, flags) |
232 | { | 232 | { |
233 | } | 233 | } |
234 | 234 | ||
235 | public Cache(CacheMedium medium, CacheStrategy strategy, | 235 | public Cache(CacheMedium medium, CacheStrategy strategy, |
236 | CacheFlags flags) | 236 | CacheFlags flags) |
237 | { | 237 | { |
238 | m_Strategy = strategy; | 238 | m_Strategy = strategy; |
239 | m_Medium = medium; | 239 | m_Medium = medium; |
240 | m_Flags = flags; | 240 | m_Flags = flags; |
241 | } | 241 | } |
242 | 242 | ||
243 | // Count of the items currently in cache | 243 | // Count of the items currently in cache |
244 | // | 244 | // |
245 | public int Count | 245 | public int Count |
246 | { | 246 | { |
247 | get { lock(m_Index) { return m_Index.Count; } } | 247 | get { lock (m_Index) { return m_Index.Count; } } |
248 | } | 248 | } |
249 | 249 | ||
250 | // Maximum number of items this cache will hold | 250 | // Maximum number of items this cache will hold |
251 | // | 251 | // |
252 | public int Size | 252 | public int Size |
253 | { | 253 | { |
254 | get { return m_Size; } | 254 | get { return m_Size; } |
255 | set { SetSize(value); } | 255 | set { SetSize(value); } |
256 | } | 256 | } |
257 | 257 | ||
258 | private void SetSize(int newSize) | 258 | private void SetSize(int newSize) |
259 | { | 259 | { |
260 | lock(m_Index) | 260 | lock (m_Index) |
261 | { | 261 | { |
262 | if(Count <= Size) | 262 | if (Count <= Size) |
263 | return; | 263 | return; |
264 | 264 | ||
265 | m_Index.Sort(new SortLRU()); | 265 | m_Index.Sort(new SortLRU()); |
266 | m_Index.Reverse(); | 266 | m_Index.Reverse(); |
267 | 267 | ||
268 | m_Index.RemoveRange(newSize, Count - newSize); | 268 | m_Index.RemoveRange(newSize, Count - newSize); |
269 | m_Size = newSize; | 269 | m_Size = newSize; |
270 | } | 270 | } |
271 | } | 271 | } |
272 | 272 | ||
273 | public TimeSpan DefaultTTL | 273 | public TimeSpan DefaultTTL |
274 | { | 274 | { |
275 | get { return m_DefaultTTL; } | 275 | get { return m_DefaultTTL; } |
276 | set { m_DefaultTTL = value; } | 276 | set { m_DefaultTTL = value; } |
277 | } | 277 | } |
278 | 278 | ||
279 | // Get an item from cache. Return the raw item, not it's data | 279 | // Get an item from cache. Return the raw item, not it's data |
280 | // | 280 | // |
281 | protected virtual CacheItemBase GetItem(LLUUID index) | 281 | protected virtual CacheItemBase GetItem(LLUUID index) |
282 | { | 282 | { |
283 | CacheItemBase item = null; | 283 | CacheItemBase item = null; |
284 | 284 | ||
285 | lock(m_Index) | 285 | lock (m_Index) |
286 | { | 286 | { |
287 | item = m_Index.Find(delegate(CacheItemBase i) | 287 | item = m_Index.Find(delegate(CacheItemBase i) |
288 | { | 288 | { |
289 | if(i.uuid == index) | 289 | if (i.uuid == index) |
290 | return true; | 290 | return true; |
291 | return false; | 291 | return false; |
292 | }); | 292 | }); |
293 | } | 293 | } |
294 | 294 | ||
295 | if(item == null) | 295 | if (item == null) |
296 | { | 296 | { |
297 | Expire(true); | 297 | Expire(true); |
298 | return null; | 298 | return null; |
299 | } | 299 | } |
300 | 300 | ||
301 | item.hits++; | 301 | item.hits++; |
302 | item.lastUsed = DateTime.Now; | 302 | item.lastUsed = DateTime.Now; |
303 | 303 | ||
304 | Expire(true); | 304 | Expire(true); |
305 | 305 | ||
306 | return item; | 306 | return item; |
307 | } | 307 | } |
308 | 308 | ||
309 | // Get an item from cache. Do not try to fetch from source if not | 309 | // Get an item from cache. Do not try to fetch from source if not |
310 | // present. Just return null | 310 | // present. Just return null |
311 | // | 311 | // |
312 | public virtual Object Get(LLUUID index) | 312 | public virtual Object Get(LLUUID index) |
313 | { | 313 | { |
314 | CacheItemBase item = GetItem(index); | 314 | CacheItemBase item = GetItem(index); |
315 | 315 | ||
316 | if(item == null) | 316 | if (item == null) |
317 | return null; | 317 | return null; |
318 | 318 | ||
319 | return item.Retrieve(); | 319 | return item.Retrieve(); |
320 | } | 320 | } |
321 | 321 | ||
322 | // Fetch an object from backing store if not cached, serve from | 322 | // Fetch an object from backing store if not cached, serve from |
323 | // cache if it is. | 323 | // cache if it is. |
324 | // | 324 | // |
325 | public virtual Object Get(LLUUID index, FetchDelegate fetch) | 325 | public virtual Object Get(LLUUID index, FetchDelegate fetch) |
326 | { | 326 | { |
327 | Object item = Get(index); | 327 | Object item = Get(index); |
328 | if(item != null) | 328 | if (item != null) |
329 | return item; | 329 | return item; |
330 | 330 | ||
331 | Object data = fetch(index); | 331 | Object data = fetch(index); |
332 | if(data == null) | 332 | if (data == null) |
333 | { | 333 | { |
334 | if((m_Flags & CacheFlags.CacheMissing) != 0) | 334 | if ((m_Flags & CacheFlags.CacheMissing) != 0) |
335 | { | 335 | { |
336 | lock(m_Index) | 336 | lock (m_Index) |
337 | { | 337 | { |
338 | CacheItemBase missing = new CacheItemBase(index); | 338 | CacheItemBase missing = new CacheItemBase(index); |
339 | if(!m_Index.Contains(missing)) | 339 | if (!m_Index.Contains(missing)) |
340 | m_Index.Add(missing); | 340 | m_Index.Add(missing); |
341 | } | 341 | } |
342 | } | 342 | } |
343 | return null; | 343 | return null; |
344 | } | 344 | } |
345 | 345 | ||
346 | Store(index, data); | 346 | Store(index, data); |
347 | 347 | ||
348 | return data; | 348 | return data; |
349 | } | 349 | } |
350 | 350 | ||
351 | 351 | ||
352 | public virtual void Store(LLUUID index, Object data) | 352 | public virtual void Store(LLUUID index, Object data) |
353 | { | 353 | { |
354 | Type container; | 354 | Type container; |
355 | 355 | ||
356 | switch(m_Medium) | 356 | switch (m_Medium) |
357 | { | 357 | { |
358 | case CacheMedium.Memory: | 358 | case CacheMedium.Memory: |
359 | container = typeof(MemoryCacheItem); | 359 | container = typeof(MemoryCacheItem); |
360 | break; | 360 | break; |
361 | case CacheMedium.File: | 361 | case CacheMedium.File: |
362 | return; | 362 | return; |
363 | default: | 363 | default: |
364 | return; | 364 | return; |
365 | } | 365 | } |
366 | 366 | ||
367 | Store(index, data, container); | 367 | Store(index, data, container); |
368 | } | 368 | } |
369 | 369 | ||
370 | public virtual void Store(LLUUID index, Object data, Type container) | 370 | public virtual void Store(LLUUID index, Object data, Type container) |
371 | { | 371 | { |
372 | Store(index, data, container, new Object[] { index }); | 372 | Store(index, data, container, new Object[] { index }); |
373 | } | 373 | } |
374 | 374 | ||
375 | public virtual void Store(LLUUID index, Object data, Type container, | 375 | public virtual void Store(LLUUID index, Object data, Type container, |
376 | Object[] parameters) | 376 | Object[] parameters) |
377 | { | 377 | { |
378 | Expire(false); | 378 | Expire(false); |
379 | 379 | ||
380 | CacheItemBase item; | 380 | CacheItemBase item; |
381 | 381 | ||
382 | lock(m_Index) | 382 | lock (m_Index) |
383 | { | 383 | { |
384 | if(m_Index.Contains(new CacheItemBase(index))) | 384 | if (m_Index.Contains(new CacheItemBase(index))) |
385 | { | 385 | { |
386 | if((m_Flags & CacheFlags.AllowUpdate) != 0) | 386 | if ((m_Flags & CacheFlags.AllowUpdate) != 0) |
387 | { | 387 | { |
388 | item = GetItem(index); | 388 | item = GetItem(index); |
389 | 389 | ||
390 | item.hits++; | 390 | item.hits++; |
391 | item.lastUsed = DateTime.Now; | 391 | item.lastUsed = DateTime.Now; |
392 | if(m_DefaultTTL.Ticks != 0) | 392 | if (m_DefaultTTL.Ticks != 0) |
393 | item.expires = DateTime.Now + m_DefaultTTL; | 393 | item.expires = DateTime.Now + m_DefaultTTL; |
394 | 394 | ||
395 | item.Store(data); | 395 | item.Store(data); |
396 | } | 396 | } |
397 | return; | 397 | return; |
398 | } | 398 | } |
399 | 399 | ||
400 | item = (CacheItemBase)Activator.CreateInstance(container, | 400 | item = (CacheItemBase)Activator.CreateInstance(container, |
401 | parameters); | 401 | parameters); |
402 | 402 | ||
403 | if(m_DefaultTTL.Ticks != 0) | 403 | if (m_DefaultTTL.Ticks != 0) |
404 | item.expires = DateTime.Now + m_DefaultTTL; | 404 | item.expires = DateTime.Now + m_DefaultTTL; |
405 | 405 | ||
406 | m_Index.Add(item); | 406 | m_Index.Add(item); |
407 | } | 407 | } |
408 | item.Store(data); | 408 | item.Store(data); |
409 | } | 409 | } |
410 | 410 | ||
411 | protected virtual void Expire(bool getting) | 411 | protected virtual void Expire(bool getting) |
412 | { | 412 | { |
413 | if(getting && (m_Strategy == CacheStrategy.Aggressive)) | 413 | if (getting && (m_Strategy == CacheStrategy.Aggressive)) |
414 | return; | 414 | return; |
415 | 415 | ||
416 | if(m_DefaultTTL.Ticks != 0) | 416 | if (m_DefaultTTL.Ticks != 0) |
417 | { | 417 | { |
418 | DateTime now= System.DateTime.Now; | 418 | DateTime now= System.DateTime.Now; |
419 | 419 | ||
420 | foreach (CacheItemBase item in new List<CacheItemBase>(m_Index)) | 420 | foreach (CacheItemBase item in new List<CacheItemBase>(m_Index)) |
421 | { | 421 | { |
422 | if(item.expires.Ticks == 0 || | 422 | if (item.expires.Ticks == 0 || |
423 | item.expires <= now) | 423 | item.expires <= now) |
424 | m_Index.Remove(item); | 424 | m_Index.Remove(item); |
425 | } | 425 | } |
426 | } | 426 | } |
427 | 427 | ||
428 | switch (m_Strategy) | 428 | switch (m_Strategy) |
429 | { | 429 | { |
430 | case CacheStrategy.Aggressive: | 430 | case CacheStrategy.Aggressive: |
431 | if(Count < Size) | 431 | if (Count < Size) |
432 | return; | 432 | return; |
433 | 433 | ||
434 | lock(m_Index) | 434 | lock (m_Index) |
435 | { | 435 | { |
436 | m_Index.Sort(new SortLRU()); | 436 | m_Index.Sort(new SortLRU()); |
437 | m_Index.Reverse(); | 437 | m_Index.Reverse(); |
438 | 438 | ||
439 | int target = (int)((float)Size * 0.9); | 439 | int target = (int)((float)Size * 0.9); |
440 | if(target == Count) // Cover ridiculous cache sizes | 440 | if (target == Count) // Cover ridiculous cache sizes |
441 | return; | 441 | return; |
442 | 442 | ||
443 | ExpireDelegate doExpire = OnExpire; | 443 | ExpireDelegate doExpire = OnExpire; |
444 | 444 | ||
445 | if(doExpire != null) | 445 | if (doExpire != null) |
446 | { | 446 | { |
447 | List<CacheItemBase> candidates = | 447 | List<CacheItemBase> candidates = |
448 | m_Index.GetRange(target, Count - target); | 448 | m_Index.GetRange(target, Count - target); |
449 | 449 | ||
450 | foreach (CacheItemBase i in candidates) | 450 | foreach (CacheItemBase i in candidates) |
451 | { | 451 | { |
452 | if(doExpire(i.uuid)) | 452 | if (doExpire(i.uuid)) |
453 | m_Index.Remove(i); | 453 | m_Index.Remove(i); |
454 | } | 454 | } |
455 | } | 455 | } |
456 | else | 456 | else |
457 | { | 457 | { |
458 | m_Index.RemoveRange(target, Count - target); | 458 | m_Index.RemoveRange(target, Count - target); |
459 | } | 459 | } |
460 | } | 460 | } |
461 | break; | 461 | break; |
462 | default: | 462 | default: |
463 | break; | 463 | break; |
464 | } | 464 | } |
465 | } | 465 | } |
466 | } | 466 | } |
467 | } | 467 | } |