Update svn properties, minor formatting cleanup.
parent
1040f3f454
commit
657af5e611
|
@ -4,464 +4,464 @@ using libsecondlife;
|
||||||
|
|
||||||
namespace Opensim.Framework
|
namespace Opensim.Framework
|
||||||
{
|
{
|
||||||
// The delegate we will use for performing fetch from backing store
|
// The delegate we will use for performing fetch from backing store
|
||||||
//
|
//
|
||||||
public delegate Object FetchDelegate(LLUUID index);
|
public delegate Object FetchDelegate(LLUUID index);
|
||||||
public delegate bool ExpireDelegate(LLUUID index);
|
public delegate bool ExpireDelegate(LLUUID index);
|
||||||
|
|
||||||
// Strategy
|
// Strategy
|
||||||
//
|
//
|
||||||
// Conservative = Minimize memory. Expire items quickly.
|
// Conservative = Minimize memory. Expire items quickly.
|
||||||
// Balanced = Expire items with few hits quickly.
|
// Balanced = Expire items with few hits quickly.
|
||||||
// Aggressive = Keep cache full. Expire only when over 90% and adding
|
// Aggressive = Keep cache full. Expire only when over 90% and adding
|
||||||
//
|
//
|
||||||
public enum CacheStrategy
|
public enum CacheStrategy
|
||||||
{
|
{
|
||||||
Conservative = 0,
|
Conservative = 0,
|
||||||
Balanced = 1,
|
Balanced = 1,
|
||||||
Aggressive = 2
|
Aggressive = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select classes to store data on different media
|
// Select classes to store data on different media
|
||||||
//
|
//
|
||||||
public enum CacheMedium
|
public enum CacheMedium
|
||||||
{
|
{
|
||||||
Memory = 0,
|
Memory = 0,
|
||||||
File = 1
|
File = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CacheFlags
|
public enum CacheFlags
|
||||||
{
|
{
|
||||||
CacheMissing = 1,
|
CacheMissing = 1,
|
||||||
AllowUpdate = 2
|
AllowUpdate = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// The base class of all cache objects. Implements comparison and sorting
|
// The base class of all cache objects. Implements comparison and sorting
|
||||||
// by the LLUUID member.
|
// by the LLUUID member.
|
||||||
//
|
//
|
||||||
// This is not abstract because we need to instantiate it briefly as a
|
// This is not abstract because we need to instantiate it briefly as a
|
||||||
// method parameter
|
// method parameter
|
||||||
//
|
//
|
||||||
public class CacheItemBase : IEquatable<CacheItemBase>, IComparable<CacheItemBase>
|
public class CacheItemBase : IEquatable<CacheItemBase>, IComparable<CacheItemBase>
|
||||||
{
|
{
|
||||||
public LLUUID uuid;
|
public LLUUID uuid;
|
||||||
public DateTime entered;
|
public DateTime entered;
|
||||||
public DateTime lastUsed;
|
public DateTime lastUsed;
|
||||||
public DateTime expires = new DateTime(0);
|
public DateTime expires = new DateTime(0);
|
||||||
public int hits = 0;
|
public int hits = 0;
|
||||||
|
|
||||||
public virtual Object Retrieve()
|
public virtual Object Retrieve()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Store(Object data)
|
public virtual void Store(Object data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheItemBase(LLUUID index)
|
public CacheItemBase(LLUUID index)
|
||||||
{
|
{
|
||||||
uuid = index;
|
uuid = index;
|
||||||
entered = DateTime.Now;
|
entered = DateTime.Now;
|
||||||
lastUsed = entered;
|
lastUsed = entered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheItemBase(LLUUID index, DateTime ttl)
|
public CacheItemBase(LLUUID index, DateTime ttl)
|
||||||
{
|
{
|
||||||
uuid = index;
|
uuid = index;
|
||||||
entered = DateTime.Now;
|
entered = DateTime.Now;
|
||||||
lastUsed = entered;
|
lastUsed = entered;
|
||||||
expires = ttl;
|
expires = ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool Equals(CacheItemBase item)
|
public virtual bool Equals(CacheItemBase item)
|
||||||
{
|
{
|
||||||
return uuid == item.uuid;
|
return uuid == item.uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int CompareTo(CacheItemBase item)
|
public virtual int CompareTo(CacheItemBase item)
|
||||||
{
|
{
|
||||||
return uuid.CompareTo(item.uuid);
|
return uuid.CompareTo(item.uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool IsLocked()
|
public virtual bool IsLocked()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple in-memory storage. Boxes the object and stores it in a variable
|
// Simple in-memory storage. Boxes the object and stores it in a variable
|
||||||
//
|
//
|
||||||
public class MemoryCacheItem : CacheItemBase
|
public class MemoryCacheItem : CacheItemBase
|
||||||
{
|
{
|
||||||
private Object m_Data;
|
private Object m_Data;
|
||||||
|
|
||||||
public MemoryCacheItem(LLUUID index) :
|
public MemoryCacheItem(LLUUID index) :
|
||||||
base(index)
|
base(index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryCacheItem(LLUUID index, DateTime ttl) :
|
public MemoryCacheItem(LLUUID index, DateTime ttl) :
|
||||||
base(index, ttl)
|
base(index, ttl)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryCacheItem(LLUUID index, Object data) :
|
public MemoryCacheItem(LLUUID index, Object data) :
|
||||||
base(index)
|
base(index)
|
||||||
{
|
{
|
||||||
Store(data);
|
Store(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryCacheItem(LLUUID index, DateTime ttl, Object data) :
|
public MemoryCacheItem(LLUUID index, DateTime ttl, Object data) :
|
||||||
base(index, ttl)
|
base(index, ttl)
|
||||||
{
|
{
|
||||||
Store(data);
|
Store(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Object Retrieve()
|
public override Object Retrieve()
|
||||||
{
|
{
|
||||||
return m_Data;
|
return m_Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Store(Object data)
|
public override void Store(Object data)
|
||||||
{
|
{
|
||||||
m_Data = data;
|
m_Data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple persistent file storage
|
// Simple persistent file storage
|
||||||
//
|
//
|
||||||
public class FileCacheItem : CacheItemBase
|
public class FileCacheItem : CacheItemBase
|
||||||
{
|
{
|
||||||
public FileCacheItem(LLUUID index) :
|
public FileCacheItem(LLUUID index) :
|
||||||
base(index)
|
base(index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileCacheItem(LLUUID index, DateTime ttl) :
|
public FileCacheItem(LLUUID index, DateTime ttl) :
|
||||||
base(index, ttl)
|
base(index, ttl)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileCacheItem(LLUUID index, Object data) :
|
public FileCacheItem(LLUUID index, Object data) :
|
||||||
base(index)
|
base(index)
|
||||||
{
|
{
|
||||||
Store(data);
|
Store(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileCacheItem(LLUUID index, DateTime ttl, Object data) :
|
public FileCacheItem(LLUUID index, DateTime ttl, Object data) :
|
||||||
base(index, ttl)
|
base(index, ttl)
|
||||||
{
|
{
|
||||||
Store(data);
|
Store(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Object Retrieve()
|
public override Object Retrieve()
|
||||||
{
|
{
|
||||||
//TODO: Add file access code
|
//TODO: Add file access code
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Store(Object data)
|
public override void Store(Object data)
|
||||||
{
|
{
|
||||||
//TODO: Add file access code
|
//TODO: Add file access code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The main cache class. This is the class you instantiate to create
|
// The main cache class. This is the class you instantiate to create
|
||||||
// a cache
|
// a cache
|
||||||
//
|
//
|
||||||
public class Cache
|
public class Cache
|
||||||
{
|
{
|
||||||
private List<CacheItemBase> m_Index = new List<CacheItemBase>();
|
private List<CacheItemBase> m_Index = new List<CacheItemBase>();
|
||||||
|
|
||||||
private CacheStrategy m_Strategy;
|
private CacheStrategy m_Strategy;
|
||||||
private CacheMedium m_Medium;
|
private CacheMedium m_Medium;
|
||||||
private CacheFlags m_Flags = 0;
|
private CacheFlags m_Flags = 0;
|
||||||
private int m_Size = 1024;
|
private int m_Size = 1024;
|
||||||
private TimeSpan m_DefaultTTL = new TimeSpan(0);
|
private TimeSpan m_DefaultTTL = new TimeSpan(0);
|
||||||
public ExpireDelegate OnExpire;
|
public ExpireDelegate OnExpire;
|
||||||
|
|
||||||
// Comparison interfaces
|
// Comparison interfaces
|
||||||
//
|
//
|
||||||
private class SortLRU : IComparer<CacheItemBase>
|
private class SortLRU : IComparer<CacheItemBase>
|
||||||
{
|
{
|
||||||
public int Compare(CacheItemBase a, CacheItemBase b)
|
public int Compare(CacheItemBase a, CacheItemBase b)
|
||||||
{
|
{
|
||||||
if(a == null && b == null)
|
if (a == null && b == null)
|
||||||
return 0;
|
return 0;
|
||||||
if(a == null)
|
if (a == null)
|
||||||
return -1;
|
return -1;
|
||||||
if(b == null)
|
if (b == null)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return(a.lastUsed.CompareTo(b.lastUsed));
|
return(a.lastUsed.CompareTo(b.lastUsed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience constructors
|
// Convenience constructors
|
||||||
//
|
//
|
||||||
public Cache()
|
public Cache()
|
||||||
{
|
{
|
||||||
m_Strategy = CacheStrategy.Balanced;
|
m_Strategy = CacheStrategy.Balanced;
|
||||||
m_Medium = CacheMedium.Memory;
|
m_Medium = CacheMedium.Memory;
|
||||||
m_Flags = 0;
|
m_Flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache(CacheMedium medium) :
|
public Cache(CacheMedium medium) :
|
||||||
this(medium, CacheStrategy.Balanced)
|
this(medium, CacheStrategy.Balanced)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache(CacheMedium medium, CacheFlags flags) :
|
public Cache(CacheMedium medium, CacheFlags flags) :
|
||||||
this(medium, CacheStrategy.Balanced, flags)
|
this(medium, CacheStrategy.Balanced, flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache(CacheMedium medium, CacheStrategy strategy) :
|
public Cache(CacheMedium medium, CacheStrategy strategy) :
|
||||||
this(medium, strategy, 0)
|
this(medium, strategy, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache(CacheStrategy strategy, CacheFlags flags) :
|
public Cache(CacheStrategy strategy, CacheFlags flags) :
|
||||||
this(CacheMedium.Memory, strategy, flags)
|
this(CacheMedium.Memory, strategy, flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache(CacheFlags flags) :
|
public Cache(CacheFlags flags) :
|
||||||
this(CacheMedium.Memory, CacheStrategy.Balanced, flags)
|
this(CacheMedium.Memory, CacheStrategy.Balanced, flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cache(CacheMedium medium, CacheStrategy strategy,
|
public Cache(CacheMedium medium, CacheStrategy strategy,
|
||||||
CacheFlags flags)
|
CacheFlags flags)
|
||||||
{
|
{
|
||||||
m_Strategy = strategy;
|
m_Strategy = strategy;
|
||||||
m_Medium = medium;
|
m_Medium = medium;
|
||||||
m_Flags = flags;
|
m_Flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count of the items currently in cache
|
// Count of the items currently in cache
|
||||||
//
|
//
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get { lock(m_Index) { return m_Index.Count; } }
|
get { lock (m_Index) { return m_Index.Count; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximum number of items this cache will hold
|
// Maximum number of items this cache will hold
|
||||||
//
|
//
|
||||||
public int Size
|
public int Size
|
||||||
{
|
{
|
||||||
get { return m_Size; }
|
get { return m_Size; }
|
||||||
set { SetSize(value); }
|
set { SetSize(value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetSize(int newSize)
|
private void SetSize(int newSize)
|
||||||
{
|
{
|
||||||
lock(m_Index)
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
if(Count <= Size)
|
if (Count <= Size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_Index.Sort(new SortLRU());
|
m_Index.Sort(new SortLRU());
|
||||||
m_Index.Reverse();
|
m_Index.Reverse();
|
||||||
|
|
||||||
m_Index.RemoveRange(newSize, Count - newSize);
|
m_Index.RemoveRange(newSize, Count - newSize);
|
||||||
m_Size = newSize;
|
m_Size = newSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeSpan DefaultTTL
|
public TimeSpan DefaultTTL
|
||||||
{
|
{
|
||||||
get { return m_DefaultTTL; }
|
get { return m_DefaultTTL; }
|
||||||
set { m_DefaultTTL = value; }
|
set { m_DefaultTTL = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an item from cache. Return the raw item, not it's data
|
// Get an item from cache. Return the raw item, not it's data
|
||||||
//
|
//
|
||||||
protected virtual CacheItemBase GetItem(LLUUID index)
|
protected virtual CacheItemBase GetItem(LLUUID index)
|
||||||
{
|
{
|
||||||
CacheItemBase item = null;
|
CacheItemBase item = null;
|
||||||
|
|
||||||
lock(m_Index)
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
item = m_Index.Find(delegate(CacheItemBase i)
|
item = m_Index.Find(delegate(CacheItemBase i)
|
||||||
{
|
{
|
||||||
if(i.uuid == index)
|
if (i.uuid == index)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
Expire(true);
|
Expire(true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.hits++;
|
item.hits++;
|
||||||
item.lastUsed = DateTime.Now;
|
item.lastUsed = DateTime.Now;
|
||||||
|
|
||||||
Expire(true);
|
Expire(true);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an item from cache. Do not try to fetch from source if not
|
// Get an item from cache. Do not try to fetch from source if not
|
||||||
// present. Just return null
|
// present. Just return null
|
||||||
//
|
//
|
||||||
public virtual Object Get(LLUUID index)
|
public virtual Object Get(LLUUID index)
|
||||||
{
|
{
|
||||||
CacheItemBase item = GetItem(index);
|
CacheItemBase item = GetItem(index);
|
||||||
|
|
||||||
if(item == null)
|
if (item == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return item.Retrieve();
|
return item.Retrieve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch an object from backing store if not cached, serve from
|
// Fetch an object from backing store if not cached, serve from
|
||||||
// cache if it is.
|
// cache if it is.
|
||||||
//
|
//
|
||||||
public virtual Object Get(LLUUID index, FetchDelegate fetch)
|
public virtual Object Get(LLUUID index, FetchDelegate fetch)
|
||||||
{
|
{
|
||||||
Object item = Get(index);
|
Object item = Get(index);
|
||||||
if(item != null)
|
if (item != null)
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
Object data = fetch(index);
|
Object data = fetch(index);
|
||||||
if(data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
if((m_Flags & CacheFlags.CacheMissing) != 0)
|
if ((m_Flags & CacheFlags.CacheMissing) != 0)
|
||||||
{
|
{
|
||||||
lock(m_Index)
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
CacheItemBase missing = new CacheItemBase(index);
|
CacheItemBase missing = new CacheItemBase(index);
|
||||||
if(!m_Index.Contains(missing))
|
if (!m_Index.Contains(missing))
|
||||||
m_Index.Add(missing);
|
m_Index.Add(missing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Store(index, data);
|
Store(index, data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual void Store(LLUUID index, Object data)
|
public virtual void Store(LLUUID index, Object data)
|
||||||
{
|
{
|
||||||
Type container;
|
Type container;
|
||||||
|
|
||||||
switch(m_Medium)
|
switch (m_Medium)
|
||||||
{
|
{
|
||||||
case CacheMedium.Memory:
|
case CacheMedium.Memory:
|
||||||
container = typeof(MemoryCacheItem);
|
container = typeof(MemoryCacheItem);
|
||||||
break;
|
break;
|
||||||
case CacheMedium.File:
|
case CacheMedium.File:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Store(index, data, container);
|
Store(index, data, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Store(LLUUID index, Object data, Type container)
|
public virtual void Store(LLUUID index, Object data, Type container)
|
||||||
{
|
{
|
||||||
Store(index, data, container, new Object[] { index });
|
Store(index, data, container, new Object[] { index });
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Store(LLUUID index, Object data, Type container,
|
public virtual void Store(LLUUID index, Object data, Type container,
|
||||||
Object[] parameters)
|
Object[] parameters)
|
||||||
{
|
{
|
||||||
Expire(false);
|
Expire(false);
|
||||||
|
|
||||||
CacheItemBase item;
|
CacheItemBase item;
|
||||||
|
|
||||||
lock(m_Index)
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
if(m_Index.Contains(new CacheItemBase(index)))
|
if (m_Index.Contains(new CacheItemBase(index)))
|
||||||
{
|
{
|
||||||
if((m_Flags & CacheFlags.AllowUpdate) != 0)
|
if ((m_Flags & CacheFlags.AllowUpdate) != 0)
|
||||||
{
|
{
|
||||||
item = GetItem(index);
|
item = GetItem(index);
|
||||||
|
|
||||||
item.hits++;
|
item.hits++;
|
||||||
item.lastUsed = DateTime.Now;
|
item.lastUsed = DateTime.Now;
|
||||||
if(m_DefaultTTL.Ticks != 0)
|
if (m_DefaultTTL.Ticks != 0)
|
||||||
item.expires = DateTime.Now + m_DefaultTTL;
|
item.expires = DateTime.Now + m_DefaultTTL;
|
||||||
|
|
||||||
item.Store(data);
|
item.Store(data);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
item = (CacheItemBase)Activator.CreateInstance(container,
|
item = (CacheItemBase)Activator.CreateInstance(container,
|
||||||
parameters);
|
parameters);
|
||||||
|
|
||||||
if(m_DefaultTTL.Ticks != 0)
|
if (m_DefaultTTL.Ticks != 0)
|
||||||
item.expires = DateTime.Now + m_DefaultTTL;
|
item.expires = DateTime.Now + m_DefaultTTL;
|
||||||
|
|
||||||
m_Index.Add(item);
|
m_Index.Add(item);
|
||||||
}
|
}
|
||||||
item.Store(data);
|
item.Store(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Expire(bool getting)
|
protected virtual void Expire(bool getting)
|
||||||
{
|
{
|
||||||
if(getting && (m_Strategy == CacheStrategy.Aggressive))
|
if (getting && (m_Strategy == CacheStrategy.Aggressive))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(m_DefaultTTL.Ticks != 0)
|
if (m_DefaultTTL.Ticks != 0)
|
||||||
{
|
{
|
||||||
DateTime now= System.DateTime.Now;
|
DateTime now= System.DateTime.Now;
|
||||||
|
|
||||||
foreach (CacheItemBase item in new List<CacheItemBase>(m_Index))
|
foreach (CacheItemBase item in new List<CacheItemBase>(m_Index))
|
||||||
{
|
{
|
||||||
if(item.expires.Ticks == 0 ||
|
if (item.expires.Ticks == 0 ||
|
||||||
item.expires <= now)
|
item.expires <= now)
|
||||||
m_Index.Remove(item);
|
m_Index.Remove(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_Strategy)
|
switch (m_Strategy)
|
||||||
{
|
{
|
||||||
case CacheStrategy.Aggressive:
|
case CacheStrategy.Aggressive:
|
||||||
if(Count < Size)
|
if (Count < Size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock(m_Index)
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
m_Index.Sort(new SortLRU());
|
m_Index.Sort(new SortLRU());
|
||||||
m_Index.Reverse();
|
m_Index.Reverse();
|
||||||
|
|
||||||
int target = (int)((float)Size * 0.9);
|
int target = (int)((float)Size * 0.9);
|
||||||
if(target == Count) // Cover ridiculous cache sizes
|
if (target == Count) // Cover ridiculous cache sizes
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ExpireDelegate doExpire = OnExpire;
|
ExpireDelegate doExpire = OnExpire;
|
||||||
|
|
||||||
if(doExpire != null)
|
if (doExpire != null)
|
||||||
{
|
{
|
||||||
List<CacheItemBase> candidates =
|
List<CacheItemBase> candidates =
|
||||||
m_Index.GetRange(target, Count - target);
|
m_Index.GetRange(target, Count - target);
|
||||||
|
|
||||||
foreach (CacheItemBase i in candidates)
|
foreach (CacheItemBase i in candidates)
|
||||||
{
|
{
|
||||||
if(doExpire(i.uuid))
|
if (doExpire(i.uuid))
|
||||||
m_Index.Remove(i);
|
m_Index.Remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_Index.RemoveRange(target, Count - target);
|
m_Index.RemoveRange(target, Count - target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,10 +464,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
lock (m_DupeTracker)
|
lock (m_DupeTracker)
|
||||||
{
|
{
|
||||||
if(m_DupeTracker.Count < 1024)
|
if (m_DupeTracker.Count < 1024)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(System.Environment.TickCount - m_DupeTrackerLastCheck < 2000)
|
if (System.Environment.TickCount - m_DupeTrackerLastCheck < 2000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_DupeTrackerLastCheck = System.Environment.TickCount;
|
m_DupeTrackerLastCheck = System.Environment.TickCount;
|
||||||
|
@ -726,7 +726,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Assign sequence number here to prevent out of order packets
|
// Assign sequence number here to prevent out of order packets
|
||||||
packet.Header.Sequence = NextPacketSequenceNumber();
|
packet.Header.Sequence = NextPacketSequenceNumber();
|
||||||
|
|
||||||
lock(m_NeedAck)
|
lock (m_NeedAck)
|
||||||
{
|
{
|
||||||
// We want to see that packet arrive if it's reliable
|
// We want to see that packet arrive if it's reliable
|
||||||
if (packet.Header.Reliable)
|
if (packet.Header.Reliable)
|
||||||
|
|
Loading…
Reference in New Issue