From 5dc785bbf2a0197b560e94b2aa8858ad33d58504 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 4 Jul 2011 22:30:18 +0100 Subject: refactor: Split file cache manipulation code into separate methods, as has already been done for the memory cache --- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 233 ++++++++++++--------- 1 file changed, 131 insertions(+), 102 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index a8f5c99..a72cf83 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -226,7 +226,6 @@ namespace Flotsam.RegionModules.AssetCache if (m_AssetService == null) { m_AssetService = scene.RequestModuleInterface(); - } } } @@ -250,140 +249,170 @@ namespace Flotsam.RegionModules.AssetCache private void UpdateMemoryCache(string key, AssetBase asset) { - if (m_MemoryCacheEnabled) - m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); + m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); } - public void Cache(AssetBase asset) + private void UpdateFileCache(string key, AssetBase asset) { - // TODO: Spawn this off to some seperate thread to do the actual writing - if (asset != null) - { - m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); - - UpdateMemoryCache(asset.ID, asset); - - string filename = GetFileName(asset.ID); + string filename = GetFileName(asset.ID); - try + try + { + // If the file is already cached, don't cache it, just touch it so access time is updated + if (File.Exists(filename)) { - // If the file is already cached, don't cache it, just touch it so access time is updated - if (File.Exists(filename)) + File.SetLastAccessTime(filename, DateTime.Now); + } + else + { + // Once we start writing, make sure we flag that we're writing + // that object to the cache so that we don't try to write the + // same file multiple times. + lock (m_CurrentlyWriting) { - File.SetLastAccessTime(filename, DateTime.Now); - } else { - - // Once we start writing, make sure we flag that we're writing - // that object to the cache so that we don't try to write the - // same file multiple times. - lock (m_CurrentlyWriting) - { #if WAIT_ON_INPROGRESS_REQUESTS - if (m_CurrentlyWriting.ContainsKey(filename)) - { - return; - } - else - { - m_CurrentlyWriting.Add(filename, new ManualResetEvent(false)); - } + if (m_CurrentlyWriting.ContainsKey(filename)) + { + return; + } + else + { + m_CurrentlyWriting.Add(filename, new ManualResetEvent(false)); + } #else - if (m_CurrentlyWriting.Contains(filename)) - { - return; - } - else - { - m_CurrentlyWriting.Add(filename); - } -#endif - + if (m_CurrentlyWriting.Contains(filename)) + { + return; } - - Util.FireAndForget( - delegate { WriteFileCache(filename, asset); }); + else + { + m_CurrentlyWriting.Add(filename); + } +#endif } - } - catch (Exception e) - { - LogException(e); + + Util.FireAndForget( + delegate { WriteFileCache(filename, asset); }); } } + catch (Exception e) + { + LogException(e); + } } - public AssetBase Get(string id) + public void Cache(AssetBase asset) { - m_Requests++; + // TODO: Spawn this off to some seperate thread to do the actual writing + if (asset != null) + { + //m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); + if (m_MemoryCacheEnabled) + UpdateMemoryCache(asset.ID, asset); + + UpdateFileCache(asset.ID, asset); + } + } + + /// + /// Try to get an asset from the in-memory cache. + /// + /// + /// + private AssetBase GetFromMemoryCache(string id) + { AssetBase asset = null; - if (m_MemoryCacheEnabled && m_MemoryCache.TryGetValue(id, out asset)) - { + if (m_MemoryCache.TryGetValue(id, out asset)) m_MemoryHits++; - } - else + + return asset; + } + + /// + /// Try to get an asset from the file cache. + /// + /// + /// + private AssetBase GetFromFileCache(string id) + { + AssetBase asset = null; + + string filename = GetFileName(id); + if (File.Exists(filename)) { - string filename = GetFileName(id); - if (File.Exists(filename)) + FileStream stream = null; + try { - FileStream stream = null; - try - { - stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); - BinaryFormatter bformatter = new BinaryFormatter(); + stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); + BinaryFormatter bformatter = new BinaryFormatter(); - asset = (AssetBase)bformatter.Deserialize(stream); + asset = (AssetBase)bformatter.Deserialize(stream); - UpdateMemoryCache(id, asset); + UpdateMemoryCache(id, asset); - m_DiskHits++; - } - catch (System.Runtime.Serialization.SerializationException e) - { - LogException(e); + m_DiskHits++; + } + catch (System.Runtime.Serialization.SerializationException e) + { + LogException(e); - // If there was a problem deserializing the asset, the asset may - // either be corrupted OR was serialized under an old format - // {different version of AssetBase} -- we should attempt to - // delete it and re-cache - File.Delete(filename); - } - catch (Exception e) - { - LogException(e); - } - finally - { - if (stream != null) - stream.Close(); - } + // If there was a problem deserializing the asset, the asset may + // either be corrupted OR was serialized under an old format + // {different version of AssetBase} -- we should attempt to + // delete it and re-cache + File.Delete(filename); + } + catch (Exception e) + { + LogException(e); } + finally + { + if (stream != null) + stream.Close(); + } + } #if WAIT_ON_INPROGRESS_REQUESTS - // Check if we're already downloading this asset. If so, try to wait for it to - // download. - if (m_WaitOnInprogressTimeout > 0) - { - m_RequestsForInprogress++; + // Check if we're already downloading this asset. If so, try to wait for it to + // download. + if (m_WaitOnInprogressTimeout > 0) + { + m_RequestsForInprogress++; - ManualResetEvent waitEvent; - if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent)) - { - waitEvent.WaitOne(m_WaitOnInprogressTimeout); - return Get(id); - } - } -#else - // Track how often we have the problem that an asset is requested while - // it is still being downloaded by a previous request. - if (m_CurrentlyWriting.Contains(filename)) + ManualResetEvent waitEvent; + if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent)) { - m_RequestsForInprogress++; + waitEvent.WaitOne(m_WaitOnInprogressTimeout); + return Get(id); } -#endif } +#else + // Track how often we have the problem that an asset is requested while + // it is still being downloaded by a previous request. + if (m_CurrentlyWriting.Contains(filename)) + { + m_RequestsForInprogress++; + } +#endif + + return asset; + } + + public AssetBase Get(string id) + { + m_Requests++; + + AssetBase asset = null; + + if (m_MemoryCacheEnabled) + asset = GetFromMemoryCache(id); + else + asset = GetFromFileCache(id); if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) { @@ -474,9 +503,9 @@ namespace Flotsam.RegionModules.AssetCache /// removes empty tier directories. /// /// + /// private void CleanExpiredFiles(string dir, DateTime purgeLine) { - foreach (string file in Directory.GetFiles(dir)) { if (File.GetLastAccessTime(file) < purgeLine) -- cgit v1.1