gc is also a unwanted cache, so use it. With this, memcache with short expires is no longer needed
parent
7cf2e81223
commit
1ffcc59818
|
@ -78,6 +78,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
private static ulong m_RequestsForInprogress;
|
private static ulong m_RequestsForInprogress;
|
||||||
private static ulong m_DiskHits;
|
private static ulong m_DiskHits;
|
||||||
private static ulong m_MemoryHits;
|
private static ulong m_MemoryHits;
|
||||||
|
private static ulong m_weakRefHits;
|
||||||
|
|
||||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||||
private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
|
private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
|
||||||
|
@ -92,7 +93,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
private bool m_MemoryCacheEnabled = false;
|
private bool m_MemoryCacheEnabled = false;
|
||||||
|
|
||||||
// Expiration is expressed in hours.
|
// Expiration is expressed in hours.
|
||||||
private double m_MemoryExpiration = 0.001;
|
private double m_MemoryExpiration = 0.016;
|
||||||
private const double m_DefaultFileExpiration = 48;
|
private const double m_DefaultFileExpiration = 48;
|
||||||
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
|
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
|
||||||
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
|
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
|
||||||
|
@ -107,6 +108,9 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
private List<Scene> m_Scenes = new List<Scene>();
|
private List<Scene> m_Scenes = new List<Scene>();
|
||||||
private object timerLock = new object();
|
private object timerLock = new object();
|
||||||
|
|
||||||
|
private Dictionary<string,WeakReference> weakAssetReferences = new Dictionary<string, WeakReference>();
|
||||||
|
private object weakAssetReferencesLock = new object();
|
||||||
|
|
||||||
public FlotsamAssetCache()
|
public FlotsamAssetCache()
|
||||||
{
|
{
|
||||||
m_InvalidChars.AddRange(Path.GetInvalidPathChars());
|
m_InvalidChars.AddRange(Path.GetInvalidPathChars());
|
||||||
|
@ -255,12 +259,23 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (m_MemoryCacheEnabled)
|
||||||
|
m_MemoryCache = new ExpiringCache<string, AssetBase>();
|
||||||
|
|
||||||
|
lock(weakAssetReferencesLock)
|
||||||
|
weakAssetReferences = new Dictionary<string, WeakReference>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// IImprovedAssetCache
|
// IImprovedAssetCache
|
||||||
//
|
//
|
||||||
|
private void UpdateWeakReference(string key, AssetBase asset)
|
||||||
|
{
|
||||||
|
WeakReference aref = new WeakReference(asset);
|
||||||
|
lock(weakAssetReferencesLock)
|
||||||
|
weakAssetReferences[key] = aref;
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateMemoryCache(string key, AssetBase asset)
|
private void UpdateMemoryCache(string key, AssetBase asset)
|
||||||
{
|
{
|
||||||
|
@ -327,6 +342,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID);
|
//m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID);
|
||||||
|
UpdateWeakReference(asset.ID, asset);
|
||||||
|
|
||||||
if (m_MemoryCacheEnabled)
|
if (m_MemoryCacheEnabled)
|
||||||
UpdateMemoryCache(asset.ID, asset);
|
UpdateMemoryCache(asset.ID, asset);
|
||||||
|
@ -354,6 +370,25 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AssetBase GetFromWeakReference(string id)
|
||||||
|
{
|
||||||
|
AssetBase asset = null;
|
||||||
|
WeakReference aref;
|
||||||
|
|
||||||
|
lock(weakAssetReferencesLock)
|
||||||
|
{
|
||||||
|
if (weakAssetReferences.TryGetValue(id, out aref))
|
||||||
|
{
|
||||||
|
asset = aref.Target as AssetBase;
|
||||||
|
if(asset == null)
|
||||||
|
weakAssetReferences.Remove(id);
|
||||||
|
else
|
||||||
|
m_weakRefHits++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to get an asset from the in-memory cache.
|
/// Try to get an asset from the in-memory cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -477,12 +512,21 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
m_Requests++;
|
m_Requests++;
|
||||||
|
|
||||||
AssetBase asset = null;
|
AssetBase asset = null;
|
||||||
|
asset = GetFromWeakReference(id);
|
||||||
|
|
||||||
if (m_MemoryCacheEnabled)
|
if (m_MemoryCacheEnabled && asset == null)
|
||||||
|
{
|
||||||
asset = GetFromMemoryCache(id);
|
asset = GetFromMemoryCache(id);
|
||||||
|
if(asset != null)
|
||||||
|
UpdateWeakReference(id,asset);
|
||||||
|
}
|
||||||
|
|
||||||
if (asset == null && m_FileCacheEnabled)
|
if (asset == null && m_FileCacheEnabled)
|
||||||
|
{
|
||||||
asset = GetFromFileCache(id);
|
asset = GetFromFileCache(id);
|
||||||
|
if(asset != null)
|
||||||
|
UpdateWeakReference(id,asset);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_MemoryCacheEnabled && asset != null)
|
if (m_MemoryCacheEnabled && asset != null)
|
||||||
UpdateMemoryCache(id, asset);
|
UpdateMemoryCache(id, asset);
|
||||||
|
@ -494,6 +538,12 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l));
|
GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(asset == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +603,10 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_MemoryCacheEnabled)
|
if (m_MemoryCacheEnabled)
|
||||||
m_MemoryCache.Clear();
|
m_MemoryCache = new ExpiringCache<string, AssetBase>();
|
||||||
|
|
||||||
|
lock(weakAssetReferencesLock)
|
||||||
|
weakAssetReferences = new Dictionary<string, WeakReference>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CleanupExpiredFiles(object source, ElapsedEventArgs e)
|
private void CleanupExpiredFiles(object source, ElapsedEventArgs e)
|
||||||
|
@ -911,28 +964,34 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
List<string> outputLines = new List<string>();
|
List<string> outputLines = new List<string>();
|
||||||
|
|
||||||
double invReq = 100.0 / m_Requests;
|
double invReq = 100.0 / m_Requests;
|
||||||
|
|
||||||
|
double weakHitRate = m_weakRefHits * invReq;
|
||||||
|
int weakEntries = weakAssetReferences.Count;
|
||||||
|
|
||||||
double fileHitRate = m_DiskHits * invReq;
|
double fileHitRate = m_DiskHits * invReq;
|
||||||
|
double TotalHitRate = weakHitRate + fileHitRate;
|
||||||
|
|
||||||
outputLines.Add(
|
outputLines.Add(
|
||||||
string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests));
|
string.Format("Total requests: {0}", m_Requests));
|
||||||
|
outputLines.Add(
|
||||||
|
string.Format("unCollected Hit Rate: {0}% ({1} entries)", weakHitRate.ToString("0.00"),weakEntries));
|
||||||
|
outputLines.Add(
|
||||||
|
string.Format("File Hit Rate: {0}%", fileHitRate.ToString("0.00")));
|
||||||
|
|
||||||
if (m_MemoryCacheEnabled)
|
if (m_MemoryCacheEnabled)
|
||||||
{
|
{
|
||||||
double HitRate = m_MemoryHits * invReq;
|
double HitRate = m_MemoryHits * invReq;
|
||||||
|
|
||||||
outputLines.Add(
|
outputLines.Add(
|
||||||
string.Format("Memory Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests));
|
string.Format("Memory Hit Rate: {0}%", HitRate.ToString("0.00")));
|
||||||
|
|
||||||
HitRate += fileHitRate;
|
TotalHitRate += HitRate;
|
||||||
|
|
||||||
outputLines.Add(
|
|
||||||
string.Format("Total Hit Rate: {0}% for {1} requests", HitRate.ToString("0.00"), m_Requests));
|
|
||||||
}
|
}
|
||||||
|
outputLines.Add(
|
||||||
|
string.Format("Total Hit Rate: {0}%", TotalHitRate.ToString("0.00")));
|
||||||
|
|
||||||
outputLines.Add(
|
outputLines.Add(
|
||||||
string.Format(
|
string.Format(
|
||||||
"Unnecessary requests due to requests for assets that are currently downloading: {0}",
|
"Requests overlap during file writing: {0}", m_RequestsForInprogress));
|
||||||
m_RequestsForInprogress));
|
|
||||||
|
|
||||||
return outputLines;
|
return outputLines;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
; Set to false for no memory cache
|
; Set to false for no memory cache
|
||||||
; assets can be requested several times in short periods
|
; assets can be requested several times in short periods
|
||||||
; so even a small memory cache is useful
|
; so even a small memory cache is useful
|
||||||
MemoryCacheEnabled = true
|
MemoryCacheEnabled = false
|
||||||
|
|
||||||
; Set to false for no file cache
|
; Set to false for no file cache
|
||||||
FileCacheEnabled = true
|
FileCacheEnabled = true
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
; this is good if memory is not a problem.
|
; this is good if memory is not a problem.
|
||||||
; if memory is a problem then a few seconds may actually save same.
|
; if memory is a problem then a few seconds may actually save same.
|
||||||
; see hit rates with console comand: fcache status
|
; see hit rates with console comand: fcache status
|
||||||
MemoryCacheTimeout = .001 ; 3.6s ie around 4s (1s resolution)
|
MemoryCacheTimeout = .016 // one minute
|
||||||
|
|
||||||
; How long {in hours} to keep assets cached on disk, .5 == 30 minutes
|
; How long {in hours} to keep assets cached on disk, .5 == 30 minutes
|
||||||
; Specify 0 if you do not want your disk cache to expire
|
; Specify 0 if you do not want your disk cache to expire
|
||||||
|
|
Loading…
Reference in New Issue