diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Asset')
-rw-r--r-- | OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 83 |
1 files changed, 71 insertions, 12 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index b6dd565..7bb88b9 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -78,6 +78,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
78 | private static ulong m_RequestsForInprogress; | 78 | private static ulong m_RequestsForInprogress; |
79 | private static ulong m_DiskHits; | 79 | private static ulong m_DiskHits; |
80 | private static ulong m_MemoryHits; | 80 | private static ulong m_MemoryHits; |
81 | private static ulong m_weakRefHits; | ||
81 | 82 | ||
82 | #if WAIT_ON_INPROGRESS_REQUESTS | 83 | #if WAIT_ON_INPROGRESS_REQUESTS |
83 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); | 84 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); |
@@ -92,7 +93,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
92 | private bool m_MemoryCacheEnabled = false; | 93 | private bool m_MemoryCacheEnabled = false; |
93 | 94 | ||
94 | // Expiration is expressed in hours. | 95 | // Expiration is expressed in hours. |
95 | private double m_MemoryExpiration = 0.001; | 96 | private double m_MemoryExpiration = 0.016; |
96 | private const double m_DefaultFileExpiration = 48; | 97 | private const double m_DefaultFileExpiration = 48; |
97 | private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); | 98 | private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); |
98 | private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); | 99 | private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0); |
@@ -107,6 +108,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
107 | private List<Scene> m_Scenes = new List<Scene>(); | 108 | private List<Scene> m_Scenes = new List<Scene>(); |
108 | private object timerLock = new object(); | 109 | private object timerLock = new object(); |
109 | 110 | ||
111 | private Dictionary<string,WeakReference> weakAssetReferences = new Dictionary<string, WeakReference>(); | ||
112 | private object weakAssetReferencesLock = new object(); | ||
113 | |||
110 | public FlotsamAssetCache() | 114 | public FlotsamAssetCache() |
111 | { | 115 | { |
112 | m_InvalidChars.AddRange(Path.GetInvalidPathChars()); | 116 | m_InvalidChars.AddRange(Path.GetInvalidPathChars()); |
@@ -255,12 +259,23 @@ namespace OpenSim.Region.CoreModules.Asset | |||
255 | } | 259 | } |
256 | } | 260 | } |
257 | } | 261 | } |
262 | if (m_MemoryCacheEnabled) | ||
263 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); | ||
264 | |||
265 | lock(weakAssetReferencesLock) | ||
266 | weakAssetReferences = new Dictionary<string, WeakReference>(); | ||
258 | } | 267 | } |
259 | } | 268 | } |
260 | 269 | ||
261 | //////////////////////////////////////////////////////////// | 270 | //////////////////////////////////////////////////////////// |
262 | // IImprovedAssetCache | 271 | // IImprovedAssetCache |
263 | // | 272 | // |
273 | private void UpdateWeakReference(string key, AssetBase asset) | ||
274 | { | ||
275 | WeakReference aref = new WeakReference(asset); | ||
276 | lock(weakAssetReferencesLock) | ||
277 | weakAssetReferences[key] = aref; | ||
278 | } | ||
264 | 279 | ||
265 | private void UpdateMemoryCache(string key, AssetBase asset) | 280 | private void UpdateMemoryCache(string key, AssetBase asset) |
266 | { | 281 | { |
@@ -327,6 +342,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
327 | if (asset != null) | 342 | if (asset != null) |
328 | { | 343 | { |
329 | //m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); | 344 | //m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); |
345 | UpdateWeakReference(asset.ID, asset); | ||
330 | 346 | ||
331 | if (m_MemoryCacheEnabled) | 347 | if (m_MemoryCacheEnabled) |
332 | UpdateMemoryCache(asset.ID, asset); | 348 | UpdateMemoryCache(asset.ID, asset); |
@@ -354,6 +370,25 @@ namespace OpenSim.Region.CoreModules.Asset | |||
354 | } | 370 | } |
355 | } | 371 | } |
356 | 372 | ||
373 | private AssetBase GetFromWeakReference(string id) | ||
374 | { | ||
375 | AssetBase asset = null; | ||
376 | WeakReference aref; | ||
377 | |||
378 | lock(weakAssetReferencesLock) | ||
379 | { | ||
380 | if (weakAssetReferences.TryGetValue(id, out aref)) | ||
381 | { | ||
382 | asset = aref.Target as AssetBase; | ||
383 | if(asset == null) | ||
384 | weakAssetReferences.Remove(id); | ||
385 | else | ||
386 | m_weakRefHits++; | ||
387 | } | ||
388 | } | ||
389 | return asset; | ||
390 | } | ||
391 | |||
357 | /// <summary> | 392 | /// <summary> |
358 | /// Try to get an asset from the in-memory cache. | 393 | /// Try to get an asset from the in-memory cache. |
359 | /// </summary> | 394 | /// </summary> |
@@ -477,12 +512,21 @@ namespace OpenSim.Region.CoreModules.Asset | |||
477 | m_Requests++; | 512 | m_Requests++; |
478 | 513 | ||
479 | AssetBase asset = null; | 514 | AssetBase asset = null; |
515 | asset = GetFromWeakReference(id); | ||
480 | 516 | ||
481 | if (m_MemoryCacheEnabled) | 517 | if (m_MemoryCacheEnabled && asset == null) |
518 | { | ||
482 | asset = GetFromMemoryCache(id); | 519 | asset = GetFromMemoryCache(id); |
520 | if(asset != null) | ||
521 | UpdateWeakReference(id,asset); | ||
522 | } | ||
483 | 523 | ||
484 | if (asset == null && m_FileCacheEnabled) | 524 | if (asset == null && m_FileCacheEnabled) |
525 | { | ||
485 | asset = GetFromFileCache(id); | 526 | asset = GetFromFileCache(id); |
527 | if(asset != null) | ||
528 | UpdateWeakReference(id,asset); | ||
529 | } | ||
486 | 530 | ||
487 | if (m_MemoryCacheEnabled && asset != null) | 531 | if (m_MemoryCacheEnabled && asset != null) |
488 | UpdateMemoryCache(id, asset); | 532 | UpdateMemoryCache(id, asset); |
@@ -494,6 +538,12 @@ namespace OpenSim.Region.CoreModules.Asset | |||
494 | GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); | 538 | GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); |
495 | } | 539 | } |
496 | 540 | ||
541 | if(asset == null) | ||
542 | { | ||
543 | |||
544 | |||
545 | } | ||
546 | |||
497 | return asset; | 547 | return asset; |
498 | } | 548 | } |
499 | 549 | ||
@@ -553,7 +603,10 @@ namespace OpenSim.Region.CoreModules.Asset | |||
553 | } | 603 | } |
554 | 604 | ||
555 | if (m_MemoryCacheEnabled) | 605 | if (m_MemoryCacheEnabled) |
556 | m_MemoryCache.Clear(); | 606 | m_MemoryCache = new ExpiringCache<string, AssetBase>(); |
607 | |||
608 | lock(weakAssetReferencesLock) | ||
609 | weakAssetReferences = new Dictionary<string, WeakReference>(); | ||
557 | } | 610 | } |
558 | 611 | ||
559 | private void CleanupExpiredFiles(object source, ElapsedEventArgs e) | 612 | private void CleanupExpiredFiles(object source, ElapsedEventArgs e) |
@@ -911,28 +964,34 @@ namespace OpenSim.Region.CoreModules.Asset | |||
911 | List<string> outputLines = new List<string>(); | 964 | List<string> outputLines = new List<string>(); |
912 | 965 | ||
913 | double invReq = 100.0 / m_Requests; | 966 | double invReq = 100.0 / m_Requests; |
967 | |||
968 | double weakHitRate = m_weakRefHits * invReq; | ||
969 | int weakEntries = weakAssetReferences.Count; | ||
914 | 970 | ||
915 | double fileHitRate = m_DiskHits * invReq; | 971 | double fileHitRate = m_DiskHits * invReq; |
972 | double TotalHitRate = weakHitRate + fileHitRate; | ||
973 | |||
974 | outputLines.Add( | ||
975 | string.Format("Total requests: {0}", m_Requests)); | ||
976 | outputLines.Add( | ||
977 | string.Format("unCollected Hit Rate: {0}% ({1} entries)", weakHitRate.ToString("0.00"),weakEntries)); | ||
916 | outputLines.Add( | 978 | outputLines.Add( |
917 | string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); | 979 | string.Format("File Hit Rate: {0}%", fileHitRate.ToString("0.00"))); |
918 | 980 | ||
919 | if (m_MemoryCacheEnabled) | 981 | if (m_MemoryCacheEnabled) |
920 | { | 982 | { |
921 | double HitRate = m_MemoryHits * invReq; | 983 | double HitRate = m_MemoryHits * invReq; |
922 | |||
923 | outputLines.Add( | 984 | outputLines.Add( |
924 | string.Format("Memory Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests)); | 985 | string.Format("Memory Hit Rate: {0}%", HitRate.ToString("0.00"))); |
925 | |||
926 | HitRate += fileHitRate; | ||
927 | 986 | ||
928 | outputLines.Add( | 987 | TotalHitRate += HitRate; |
929 | string.Format("Total Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests)); | ||
930 | } | 988 | } |
989 | outputLines.Add( | ||
990 | string.Format("Total Hit Rate: {0}%", TotalHitRate.ToString("0.00"))); | ||
931 | 991 | ||
932 | outputLines.Add( | 992 | outputLines.Add( |
933 | string.Format( | 993 | string.Format( |
934 | "Unnecessary requests due to requests for assets that are currently downloading: {0}", | 994 | "Requests overlap during file writing: {0}", m_RequestsForInprogress)); |
935 | m_RequestsForInprogress)); | ||
936 | 995 | ||
937 | return outputLines; | 996 | return outputLines; |
938 | } | 997 | } |