Thank you Imaze Rhiano for a patch that implements Cenome Memory Asset Cache (Mantis #3759)
See the files: bin/config-include/GridCommon.ini.example and bin/config-include/StandaloneCommon.ini.example to configure and enable this caching method.0.6.6-post-fixes
parent
23bf1bf6e0
commit
b38be1a7fd
|
@ -73,6 +73,7 @@ what it is today.
|
||||||
* Ewe Loon
|
* Ewe Loon
|
||||||
* Fly-Man
|
* Fly-Man
|
||||||
* Flyte Xevious
|
* Flyte Xevious
|
||||||
|
* Imaze Rhiano
|
||||||
* Intimidated
|
* Intimidated
|
||||||
* Jeremy Bongio (IBM)
|
* Jeremy Bongio (IBM)
|
||||||
* jhurliman
|
* jhurliman
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,746 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Synchronized Cenome cache wrapper.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">
|
||||||
|
/// The type of keys in the cache.
|
||||||
|
/// </typeparam>
|
||||||
|
/// <typeparam name="TValue">
|
||||||
|
/// The type of values in the cache.
|
||||||
|
/// </typeparam>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Enumerator will block other threads, until enumerator's <see cref="IDisposable.Dispose"/> method is called.
|
||||||
|
/// "foreach" statement is automatically calling it.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public class CnmSynchronizedCache<TKey, TValue> : ICnmCache<TKey, TValue>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The cache object.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ICnmCache<TKey, TValue> m_cache;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Synchronization root.
|
||||||
|
/// </summary>
|
||||||
|
private readonly object m_syncRoot;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CnmSynchronizedCache{TKey,TValue}"/> class.
|
||||||
|
/// Initializes a new instance of the <see cref="CnmSynchronizedCache{TKey,TValue}"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cache">
|
||||||
|
/// The cache.
|
||||||
|
/// </param>
|
||||||
|
private CnmSynchronizedCache( ICnmCache<TKey, TValue> cache )
|
||||||
|
{
|
||||||
|
m_cache = cache;
|
||||||
|
m_syncRoot = m_cache.SyncRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="ICnmCache{TKey,TValue}"/> wrapper that is synchronized (thread safe).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cache">
|
||||||
|
/// The <see cref="ICnmCache{TKey,TValue}"/> to synchronize.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="ICnmCache{TKey,TValue}"/> wrapper that is synchronized (thread safe).
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="cache"/>is null.
|
||||||
|
/// </exception>
|
||||||
|
public static ICnmCache<TKey, TValue> Synchronized( ICnmCache<TKey, TValue> cache )
|
||||||
|
{
|
||||||
|
if( cache == null )
|
||||||
|
throw new ArgumentNullException( "cache" );
|
||||||
|
return cache.IsSynchronized ? cache : new CnmSynchronizedCache<TKey, TValue>( cache );
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Nested type: SynchronizedEnumerator
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Synchronized enumerator.
|
||||||
|
/// </summary>
|
||||||
|
private class SynchronizedEnumerator : IEnumerator<KeyValuePair<TKey, TValue>>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enumerator that is being synchronized.
|
||||||
|
/// </summary>
|
||||||
|
private readonly IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Synchronization root.
|
||||||
|
/// </summary>
|
||||||
|
private object m_syncRoot;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SynchronizedEnumerator"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enumerator">
|
||||||
|
/// The enumerator that is being synchronized.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="syncRoot">
|
||||||
|
/// The sync root.
|
||||||
|
/// </param>
|
||||||
|
public SynchronizedEnumerator( IEnumerator<KeyValuePair<TKey, TValue>> enumerator, object syncRoot )
|
||||||
|
{
|
||||||
|
m_syncRoot = syncRoot;
|
||||||
|
m_enumerator = enumerator;
|
||||||
|
Monitor.Enter( m_syncRoot );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes an instance of the <see cref="SynchronizedEnumerator"/> class.
|
||||||
|
/// </summary>
|
||||||
|
~SynchronizedEnumerator()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IEnumerator<KeyValuePair<TKey,TValue>> Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the element in the collection at the current position of the enumerator.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The element in the collection at the current position of the enumerator.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The enumerator has reach end of collection or <see cref="MoveNext"/> is not called.
|
||||||
|
/// </exception>
|
||||||
|
public KeyValuePair<TKey, TValue> Current
|
||||||
|
{
|
||||||
|
get { return m_enumerator.Current; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current element in the collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The current element in the collection.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The enumerator is positioned before the first element of the collection or after the last element.
|
||||||
|
/// </exception><filterpriority>2</filterpriority>
|
||||||
|
object IEnumerator.Current
|
||||||
|
{
|
||||||
|
get { return Current; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases synchronization lock.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if( m_syncRoot != null )
|
||||||
|
{
|
||||||
|
Monitor.Exit( m_syncRoot );
|
||||||
|
m_syncRoot = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enumerator.Dispose();
|
||||||
|
GC.SuppressFinalize( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advances the enumerator to the next element of the collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The collection was modified after the enumerator was created.
|
||||||
|
/// </exception>
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
return m_enumerator.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the enumerator to its initial position, which is before the first element in the collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The collection was modified after the enumerator was created.
|
||||||
|
/// </exception>
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
m_enumerator.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ICnmCache<TKey,TValue> Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets current count of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxCount"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets elements expiration time.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Elements expiration time.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When element has been stored in <see cref="ICnmCache{TKey,TValue}"/> longer than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
|
||||||
|
/// and it is not accessed through <see cref="ICnmCache{TKey,TValue}.TryGetValue"/> method or element's value is
|
||||||
|
/// not replaced by <see cref="ICnmCache{TKey,TValue}.Set"/> method, then it is automatically removed from the
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// It is possible that <see cref="ICnmCache{TKey,TValue}"/> implementation removes element before it's expiration time,
|
||||||
|
/// because total size or count of elements stored to cache is larger than <see cref="ICnmCache{TKey,TValue}.MaxSize"/> or <see cref="ICnmCache{TKey,TValue}.MaxCount"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// It is also possible that element stays in cache longer than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Calling <see cref="ICnmCache{TKey,TValue}.PurgeExpired"/> try to remove all elements that are expired.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// To disable time limit in cache, set <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/> to <see cref="DateTime.MaxValue"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Count"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxCount"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
|
||||||
|
public TimeSpan ExpirationTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.ExpirationTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.ExpirationTime = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting count of elements.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> count of elements is limited;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Count"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxCount"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
|
||||||
|
public bool IsCountLimited
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.IsCountLimited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting size of elements.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> total size of elements is limited;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxElementSize"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
|
||||||
|
public bool IsSizeLimited
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.IsSizeLimited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether or not access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe).
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe);
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/> object, use
|
||||||
|
/// <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> in <see cref="CnmSynchronizedCache{TKey,TValue}"/> class
|
||||||
|
/// to retrieve synchronized wrapper for <see cref="ICnmCache{TKey,TValue}"/> object.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.SyncRoot"/>
|
||||||
|
/// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
|
||||||
|
public bool IsSynchronized
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether elements stored to <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> has a fixed total size of elements;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// If <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time and element is not accessed through <see cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// or <see cref="ICnmCache{TKey,TValue}.TryGetValue"/> methods in <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/> , then element is automatically removed from
|
||||||
|
/// the cache. Depending on implementation of the <see cref="ICnmCache{TKey,TValue}"/>, some of the elements may
|
||||||
|
/// stay longer in cache.
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
public bool IsTimeLimited
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.IsTimeLimited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets maximal allowed count of elements that can be stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see cref="int.MaxValue"/>, if <see cref="ICnmCache{TKey,TValue}"/> is not limited by count of elements;
|
||||||
|
/// otherwise maximal allowed count of elements.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public int MaxCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.MaxCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.MaxCount = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Gets maximal allowed element size.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Maximal allowed element size.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// If element's size is larger than <see cref="ICnmCache{TKey,TValue}.MaxElementSize"/>, then element is
|
||||||
|
/// not added to the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
|
||||||
|
public long MaxElementSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.MaxElementSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">value is less than 0.</exception>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxElementSize"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Size"/>
|
||||||
|
public long MaxSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.MaxSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.MaxSize = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Normally bytes, but can be any suitable unit of measure.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Element's size is given when element is added or replaced by <see cref="ICnmCache{TKey,TValue}.Set"/> method.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxElementSize"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.MaxSize"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
|
||||||
|
public long Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// An object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/>, use <see cref="CnmSynchronizedCache{TKey,TValue}"/>
|
||||||
|
/// method <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> to retrieve synchronized wrapper interface to
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSynchronized"/>
|
||||||
|
/// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
|
||||||
|
public object SyncRoot
|
||||||
|
{
|
||||||
|
get { return m_syncRoot; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all elements from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an enumerator that iterates through the elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
|
||||||
|
/// </returns>
|
||||||
|
/// <filterpriority>1</filterpriority>
|
||||||
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return new SynchronizedEnumerator( m_cache.GetEnumerator(), m_syncRoot );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Purge expired elements from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Element becomes expired when last access time to it has been longer time than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Depending on <see cref="ICnmCache{TKey,TValue}"/> implementation, some of expired elements
|
||||||
|
/// may stay longer than <see cref="ICnmCache{TKey,TValue}.ExpirationTime"/> in the cache.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsTimeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.ExpirationTime"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
|
||||||
|
public void PurgeExpired()
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.PurgeExpired();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes element associated with <paramref name="key"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">
|
||||||
|
/// The key that is associated with element to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="key"/>is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
public void Remove( TKey key )
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.Remove( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes elements that are associated with one of <paramref name="keys"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keys">
|
||||||
|
/// The keys that are associated with elements to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="keys"/>is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
public void RemoveRange( IEnumerable<TKey> keys )
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
m_cache.RemoveRange( keys );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add or replace an element with the provided <paramref name="key"/>, <paramref name="value"/> and <paramref name="size"/> to
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">
|
||||||
|
/// The object used as the key of the element. Can't be <see langword="null"/> reference.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="value">
|
||||||
|
/// The object used as the value of the element to add or replace. <see langword="null"/> is allowed.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="size">
|
||||||
|
/// The element's size. Normally bytes, but can be any suitable unit of measure.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/>if element has been added successfully to the <see cref="ICnmCache{TKey,TValue}"/>;
|
||||||
|
/// otherwise <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="key"/>is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">
|
||||||
|
/// The element's <paramref name="size"/> is less than 0.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// If element's <paramref name="size"/> is larger than <see cref="ICnmCache{TKey,TValue}.MaxElementSize"/>, then element is
|
||||||
|
/// not added to the <see cref="ICnmCache{TKey,TValue}"/>, however - possible older element is
|
||||||
|
/// removed from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsSizeLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.IsCountLimited"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.TryGetValue"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
public bool Set( TKey key, TValue value, long size )
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.Set( key, value, size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <paramref name="value"/> associated with the specified <paramref name="key"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/>if the <see cref="ICnmCache{TKey,TValue}"/> contains an element with
|
||||||
|
/// the specified key; otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <param name="key">
|
||||||
|
/// The key whose <paramref name="value"/> to get.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="value">
|
||||||
|
/// When this method returns, the value associated with the specified <paramref name="key"/>,
|
||||||
|
/// if the <paramref name="key"/> is found; otherwise, the
|
||||||
|
/// default value for the type of the <paramref name="value"/> parameter. This parameter is passed uninitialized.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="key"/>is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Set"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Remove"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.RemoveRange"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.Clear"/>
|
||||||
|
/// <seealso cref="ICnmCache{TKey,TValue}.PurgeExpired"/>
|
||||||
|
public bool TryGetValue( TKey key, out TValue value )
|
||||||
|
{
|
||||||
|
lock( m_syncRoot )
|
||||||
|
{
|
||||||
|
return m_cache.TryGetValue( key, out value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an enumerator that iterates through the elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="IEnumerator"/> that can be used to iterate through the collection.
|
||||||
|
/// </returns>
|
||||||
|
/// <filterpriority>1</filterpriority>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,441 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represent generic cache to store key/value pairs (elements) limited by time, size and count of elements.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">
|
||||||
|
/// The type of keys in the cache.
|
||||||
|
/// </typeparam>
|
||||||
|
/// <typeparam name="TValue">
|
||||||
|
/// The type of values in the cache.
|
||||||
|
/// </typeparam>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Cache store limitations:
|
||||||
|
/// </para>
|
||||||
|
/// <list type="table">
|
||||||
|
/// <listheader>
|
||||||
|
/// <term>Limitation</term>
|
||||||
|
/// <description>Description</description>
|
||||||
|
/// </listheader>
|
||||||
|
/// <item>
|
||||||
|
/// <term>Time</term>
|
||||||
|
/// <description>
|
||||||
|
/// Element that is not accessed through <see cref="TryGetValue"/> or <see cref="Set"/> in last <see cref="ExpirationTime"/> are
|
||||||
|
/// removed from the cache automatically. Depending on implementation of the cache some of elements may stay longer in cache.
|
||||||
|
/// <see cref="IsTimeLimited"/> returns <see langword="true"/>, if cache is limited by time.
|
||||||
|
/// </description>
|
||||||
|
/// </item>
|
||||||
|
/// <item>
|
||||||
|
/// <term>Count</term>
|
||||||
|
/// <description>
|
||||||
|
/// When adding an new element to cache that already have <see cref="MaxCount"/> of elements, cache will remove less recently
|
||||||
|
/// used element(s) from the cache, until element fits to cache.
|
||||||
|
/// <see cref="IsCountLimited"/> returns <see langword="true"/>, if cache is limiting element count.
|
||||||
|
/// </description>
|
||||||
|
/// </item>
|
||||||
|
/// <item>
|
||||||
|
/// <term>Size</term>
|
||||||
|
/// <description>
|
||||||
|
/// <description>
|
||||||
|
/// When adding an new element to cache that already have <see cref="MaxSize"/> of elements, cache will remove less recently
|
||||||
|
/// used element(s) from the cache, until element fits to cache.
|
||||||
|
/// <see cref="IsSizeLimited"/> returns <see langword="true"/>, if cache is limiting total size of elements.
|
||||||
|
/// Normally size is bytes used by element in the cache. But it can be any other suitable unit of measure.
|
||||||
|
/// </description>
|
||||||
|
/// </description>
|
||||||
|
/// </item>
|
||||||
|
/// </list>
|
||||||
|
/// </remarks>
|
||||||
|
public interface ICnmCache<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets current count of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="MaxCount"/>
|
||||||
|
/// <seealso cref="IsCountLimited"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="IsTimeLimited"/>
|
||||||
|
int Count { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets elements expiration time.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Elements expiration time.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When element has been stored in <see cref="ICnmCache{TKey,TValue}"/> longer than <see cref="ExpirationTime"/>
|
||||||
|
/// and it is not accessed through <see cref="TryGetValue"/> method or element's value is
|
||||||
|
/// not replaced by <see cref="Set"/> method, then it is automatically removed from the
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// It is possible that <see cref="ICnmCache{TKey,TValue}"/> implementation removes element before it's expiration time,
|
||||||
|
/// because total size or count of elements stored to cache is larger than <see cref="MaxSize"/> or <see cref="MaxCount"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// It is also possible that element stays in cache longer than <see cref="ExpirationTime"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Calling <see cref="PurgeExpired"/> try to remove all elements that are expired.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// To disable time limit in cache, set <see cref="ExpirationTime"/> to <see cref="DateTime.MaxValue"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="IsTimeLimited"/>
|
||||||
|
/// <seealso cref="IsCountLimited"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
/// <seealso cref="Count"/>
|
||||||
|
/// <seealso cref="MaxCount"/>
|
||||||
|
/// <seealso cref="MaxSize"/>
|
||||||
|
/// <seealso cref="Size"/>
|
||||||
|
TimeSpan ExpirationTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether or not access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe).
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if access to the <see cref="ICnmCache{TKey,TValue}"/> is synchronized (thread safe);
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/> object, use
|
||||||
|
/// <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> in <see cref="CnmSynchronizedCache{TKey,TValue}"/> class
|
||||||
|
/// to retrieve synchronized wrapper for <see cref="ICnmCache{TKey,TValue}"/> object.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="SyncRoot"/>
|
||||||
|
/// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
|
||||||
|
bool IsSynchronized { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting count of elements.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> count of elements is limited;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="Count"/>
|
||||||
|
/// <seealso cref="MaxCount"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="IsTimeLimited"/>
|
||||||
|
bool IsCountLimited { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether <see cref="ICnmCache{TKey,TValue}"/> is limiting size of elements.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> total size of elements is limited;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="MaxElementSize"/>
|
||||||
|
/// <seealso cref="Size"/>
|
||||||
|
/// <seealso cref="MaxSize"/>
|
||||||
|
/// <seealso cref="IsCountLimited"/>
|
||||||
|
/// <seealso cref="IsTimeLimited"/>
|
||||||
|
bool IsSizeLimited { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether elements stored to <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see langword="true"/> if the <see cref="ICnmCache{TKey,TValue}"/> has a fixed total size of elements;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// If <see cref="ICnmCache{TKey,TValue}"/> have limited inactivity time and element is not accessed through <see cref="Set"/>
|
||||||
|
/// or <see cref="TryGetValue"/> methods in <see cref="ExpirationTime"/> , then element is automatically removed from
|
||||||
|
/// the cache. Depending on implementation of the <see cref="ICnmCache{TKey,TValue}"/>, some of the elements may
|
||||||
|
/// stay longer in cache.
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ExpirationTime"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
/// <seealso cref="IsCountLimited"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
bool IsTimeLimited { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets maximal allowed count of elements that can be stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <see cref="int.MaxValue"/>, if <see cref="ICnmCache{TKey,TValue}"/> is not limited by count of elements;
|
||||||
|
/// otherwise maximal allowed count of elements.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
int MaxCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Gets maximal allowed element size.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Maximal allowed element size.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// If element's size is larger than <see cref="MaxElementSize"/>, then element is
|
||||||
|
/// not added to the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="Set"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="Size"/>
|
||||||
|
/// <seealso cref="MaxSize"/>
|
||||||
|
long MaxElementSize { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Maximal allowed total size for elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Normally size is total bytes used by elements in the cache. But it can be any other suitable unit of measure.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">value is less than 0.</exception>
|
||||||
|
/// <seealso cref="MaxElementSize"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="Size"/>
|
||||||
|
long MaxSize { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Total size of elements stored to <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Normally bytes, but can be any suitable unit of measure.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Element's size is given when element is added or replaced by <see cref="Set"/> method.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/> will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="MaxElementSize"/>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="MaxSize"/>
|
||||||
|
/// <seealso cref="IsCountLimited"/>
|
||||||
|
/// <seealso cref="ExpirationTime"/>
|
||||||
|
long Size { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// An object that can be used to synchronize access to the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </value>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// To get synchronized (thread safe) access to <see cref="ICnmCache{TKey,TValue}"/>, use <see cref="CnmSynchronizedCache{TKey,TValue}"/>
|
||||||
|
/// method <see cref="CnmSynchronizedCache{TKey,TValue}.Synchronized"/> to retrieve synchronized wrapper interface to
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="IsSynchronized"/>
|
||||||
|
/// <seealso cref="CnmSynchronizedCache{TKey,TValue}"/>
|
||||||
|
object SyncRoot { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all elements from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="Set"/>
|
||||||
|
/// <seealso cref="Remove"/>
|
||||||
|
/// <seealso cref="RemoveRange"/>
|
||||||
|
/// <seealso cref="TryGetValue"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Purge expired elements from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Element becomes expired when last access time to it has been longer time than <see cref="ExpirationTime"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Depending on <see cref="ICnmCache{TKey,TValue}"/> implementation, some of expired elements
|
||||||
|
/// may stay longer than <see cref="ExpirationTime"/> in the cache.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="IsTimeLimited"/>
|
||||||
|
/// <seealso cref="ExpirationTime"/>
|
||||||
|
/// <seealso cref="Set"/>
|
||||||
|
/// <seealso cref="Remove"/>
|
||||||
|
/// <seealso cref="RemoveRange"/>
|
||||||
|
/// <seealso cref="TryGetValue"/>
|
||||||
|
/// <seealso cref="Clear"/>
|
||||||
|
void PurgeExpired();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes element associated with <paramref name="key"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">
|
||||||
|
/// The key that is associated with element to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="key"/> is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <seealso cref="Set"/>
|
||||||
|
/// <seealso cref="RemoveRange"/>
|
||||||
|
/// <seealso cref="TryGetValue"/>
|
||||||
|
/// <seealso cref="Clear"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
void Remove( TKey key );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes elements that are associated with one of <paramref name="keys"/> from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keys">
|
||||||
|
/// The keys that are associated with elements to remove from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="keys"/> is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <seealso cref="Set"/>
|
||||||
|
/// <seealso cref="Remove"/>
|
||||||
|
/// <seealso cref="TryGetValue"/>
|
||||||
|
/// <seealso cref="Clear"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
void RemoveRange( IEnumerable<TKey> keys );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add or replace an element with the provided <paramref name="key"/>, <paramref name="value"/> and <paramref name="size"/> to
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">
|
||||||
|
/// The object used as the key of the element. Can't be <see langword="null"/> reference.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="value">
|
||||||
|
/// The object used as the value of the element to add or replace. <see langword="null"/> is allowed.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="size">
|
||||||
|
/// The element's size. Normally bytes, but can be any suitable unit of measure.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if element has been added successfully to the <see cref="ICnmCache{TKey,TValue}"/>;
|
||||||
|
/// otherwise <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="key"/>is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">
|
||||||
|
/// The element's <paramref name="size"/> is less than 0.
|
||||||
|
/// </exception>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// If element's <paramref name="size"/> is larger than <see cref="MaxElementSize"/>, then element is
|
||||||
|
/// not added to the <see cref="ICnmCache{TKey,TValue}"/>, however - possible older element is
|
||||||
|
/// removed from the <see cref="ICnmCache{TKey,TValue}"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting total size of elements,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When adding an new element to <see cref="ICnmCache{TKey,TValue}"/> that is limiting element count,
|
||||||
|
/// <see cref="ICnmCache{TKey,TValue}"/>will remove less recently used elements until it can fit an new element.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="IsSizeLimited"/>
|
||||||
|
/// <seealso cref="IsCountLimited"/>
|
||||||
|
/// <seealso cref="Remove"/>
|
||||||
|
/// <seealso cref="RemoveRange"/>
|
||||||
|
/// <seealso cref="TryGetValue"/>
|
||||||
|
/// <seealso cref="Clear"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
bool Set( TKey key, TValue value, long size );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <paramref name="value"/> associated with the specified <paramref name="key"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/>if the <see cref="ICnmCache{TKey,TValue}"/> contains an element with
|
||||||
|
/// the specified key; otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <param name="key">
|
||||||
|
/// The key whose <paramref name="value"/> to get.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="value">
|
||||||
|
/// When this method returns, the value associated with the specified <paramref name="key"/>,
|
||||||
|
/// if the <paramref name="key"/> is found; otherwise, the
|
||||||
|
/// default value for the type of the <paramref name="value"/> parameter. This parameter is passed uninitialized.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
|
/// <paramref name="key"/>is <see langword="null"/>.
|
||||||
|
/// </exception>
|
||||||
|
/// <seealso cref="Set"/>
|
||||||
|
/// <seealso cref="Remove"/>
|
||||||
|
/// <seealso cref="RemoveRange"/>
|
||||||
|
/// <seealso cref="Clear"/>
|
||||||
|
/// <seealso cref="PurgeExpired"/>
|
||||||
|
bool TryGetValue( TKey key, out TValue value );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Utility class that is used to find small prime numbers and test is number prime number.
|
||||||
|
/// </summary>
|
||||||
|
public static class PrimeNumberHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Precalculated prime numbers.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly int[] Primes = new[]
|
||||||
|
{
|
||||||
|
3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239,
|
||||||
|
293, 353, 431, 521, 631, 761, 919, 1103, 1327, 1597, 1931, 2333,
|
||||||
|
2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
|
||||||
|
17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431,
|
||||||
|
90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449,
|
||||||
|
389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
|
||||||
|
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559,
|
||||||
|
5999471, 7199369
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get prime number that is equal or larger than <see cref="min"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="min">
|
||||||
|
/// Minimal returned prime number.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// Primer number that is equal or larger than <see cref="min"/>. If <see cref="min"/> is too large, return -1.
|
||||||
|
/// </returns>
|
||||||
|
public static int GetPrime( int min )
|
||||||
|
{
|
||||||
|
if( min <= 2 )
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if( Primes[ Primes.Length - 1 ] < min )
|
||||||
|
{
|
||||||
|
for( var i = min | 1 ; i < 0x7FFFFFFF ; i += 2 )
|
||||||
|
{
|
||||||
|
if( IsPrime( i ) )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( var i = Primes.Length - 2 ; i >= 0 ; i-- )
|
||||||
|
{
|
||||||
|
if( min == Primes[ i ] )
|
||||||
|
return min;
|
||||||
|
|
||||||
|
if( min > Primes[ i ] )
|
||||||
|
return Primes[ i + 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Just basic Sieve of Eratosthenes prime number test.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="candinate">
|
||||||
|
/// Number that is tested.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// true, if <see cref="candinate"/> is prime number; otherwise false.
|
||||||
|
/// </returns>
|
||||||
|
public static bool IsPrime( int candinate )
|
||||||
|
{
|
||||||
|
if( (candinate & 1) == 0 )
|
||||||
|
|
||||||
|
// Even number - only prime if 2
|
||||||
|
return candinate == 2;
|
||||||
|
|
||||||
|
var upperBound = (int) Math.Sqrt( candinate );
|
||||||
|
for( var i = 3 ; i < upperBound ; i += 2 )
|
||||||
|
{
|
||||||
|
if( candinate % i == 0 )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,381 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Asset
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Cenome memory asset cache.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Cache is enabled by setting "AssetCaching" configuration to value "CenomeMemoryAssetCache".
|
||||||
|
/// When cache is successfully enable log should have message
|
||||||
|
/// "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = XXX bytes, MaxCount = XXX, ExpirationTime = XXX)".
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Cache's size is limited by two parameters:
|
||||||
|
/// maximal allowed size in bytes and maximal allowed asset count. When new asset
|
||||||
|
/// is added to cache that have achieved either size or count limitation, cache
|
||||||
|
/// will automatically remove less recently used assets from cache. Additionally
|
||||||
|
/// asset's lifetime is controlled by expiration time.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// <list type="table">
|
||||||
|
/// <listheader>
|
||||||
|
/// <term>Configuration</term>
|
||||||
|
/// <description>Description</description>
|
||||||
|
/// </listheader>
|
||||||
|
/// <item>
|
||||||
|
/// <term>MaxSize</term>
|
||||||
|
/// <description>Maximal size of the cache in bytes. Default value: 128MB (134 217 728 bytes).</description>
|
||||||
|
/// </item>
|
||||||
|
/// <item>
|
||||||
|
/// <term>MaxCount</term>
|
||||||
|
/// <description>Maximal count of assets stored to cache. Default value: 4096 assets.</description>
|
||||||
|
/// </item>
|
||||||
|
/// <item>
|
||||||
|
/// <term>ExpirationTime</term>
|
||||||
|
/// <description>Asset's expiration time in minutes. Default value: 30 minutes.</description>
|
||||||
|
/// </item>
|
||||||
|
/// </list>
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <example>
|
||||||
|
/// Enabling Cenome Asset Cache:
|
||||||
|
/// <code>
|
||||||
|
/// [Modules]
|
||||||
|
/// AssetCaching = "CenomeMemoryAssetCache"
|
||||||
|
/// </code>
|
||||||
|
/// Setting size and expiration time limitations:
|
||||||
|
/// <code>
|
||||||
|
/// [AssetService]
|
||||||
|
/// ; 256 MB (default: 134217728)
|
||||||
|
/// MaxSize = 268435456
|
||||||
|
/// ; How many assets it is possible to store cache (default: 4096)
|
||||||
|
/// MaxCount = 16384
|
||||||
|
/// ; Expiration time - 1 hour (default: 30 minutes)
|
||||||
|
/// ExpirationTime = 60
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Cache's default maximal asset count.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Assuming that average asset size is about 32768 bytes.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public const int DefaultMaxCount = 4096;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default maximal size of the cache in bytes
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// 128MB = 128 * 1024^2 = 134 217 728 bytes.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public const long DefaultMaxSize = 134217728;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asset's default expiration time in the cache.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly TimeSpan DefaultExpirationTime = TimeSpan.FromMinutes( 30.0 );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log manager instance.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cache object.
|
||||||
|
/// </summary>
|
||||||
|
private ICnmCache<string, AssetBase> m_cache;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is Cenome asset cache enabled.
|
||||||
|
/// </summary>
|
||||||
|
private bool m_enabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Count of get requests
|
||||||
|
/// </summary>
|
||||||
|
private int m_getCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many hits
|
||||||
|
/// </summary>
|
||||||
|
private int m_hitCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Count of cache commands
|
||||||
|
/// </summary>
|
||||||
|
private int m_cachedCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many gets before dumping statistics
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If 0 or less, then disabled.
|
||||||
|
/// </remarks>
|
||||||
|
private int m_debugEpoch = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize asset cache module with default parameters.
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
Initialize( DefaultMaxSize, DefaultMaxCount, DefaultExpirationTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize asset cache module, with custom parameters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="maximalSize">
|
||||||
|
/// Cache's maximal size in bytes.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="maximalCount">
|
||||||
|
/// Cache's maximal count of assets.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="expirationTime">
|
||||||
|
/// Asset's expiration time.
|
||||||
|
/// </param>
|
||||||
|
public void Initialize( long maximalSize, int maximalCount, TimeSpan expirationTime )
|
||||||
|
{
|
||||||
|
if( maximalSize <= 0 || maximalCount <= 0 || expirationTime <= TimeSpan.Zero )
|
||||||
|
{
|
||||||
|
Log.Info( "[ASSET CACHE]: Cenome asset cache is not enabled." );
|
||||||
|
m_enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create cache and add synchronization wrapper over it
|
||||||
|
m_cache =
|
||||||
|
CnmSynchronizedCache<string, AssetBase>.Synchronized( new CnmMemoryCache<string, AssetBase>(
|
||||||
|
maximalSize, maximalCount, expirationTime ) );
|
||||||
|
m_enabled = true;
|
||||||
|
Log.InfoFormat("[ASSET CACHE]: Cenome asset cache enabled (MaxSize = {0} bytes, MaxCount = {1}, ExpirationTime = {2})", maximalSize, maximalCount, expirationTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IImprovedAssetCache Members
|
||||||
|
/// <summary>
|
||||||
|
/// Cache asset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asset">
|
||||||
|
/// The asset that is being cached.
|
||||||
|
/// </param>
|
||||||
|
public void Cache( AssetBase asset )
|
||||||
|
{
|
||||||
|
long size = asset.Data != null ? asset.Data.Length : 1;
|
||||||
|
m_cache.Set( asset.ID, asset, size );
|
||||||
|
m_cachedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear asset cache.
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
m_cache.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Expire (remove) asset stored to cache.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">
|
||||||
|
/// The expired asset's id.
|
||||||
|
/// </param>
|
||||||
|
public void Expire( string id )
|
||||||
|
{
|
||||||
|
m_cache.Remove( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get asset stored
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">
|
||||||
|
/// The asset's id.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// Asset if it is found from cache; otherwise <see langword="null"/>.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Caller should always check that is return value <see langword="null"/>.
|
||||||
|
/// Cache doesn't guarantee in any situation that asset is stored to it.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public AssetBase Get( string id )
|
||||||
|
{
|
||||||
|
m_getCount++;
|
||||||
|
AssetBase assetBase;
|
||||||
|
if( m_cache.TryGetValue( id, out assetBase ) )
|
||||||
|
m_hitCount++;
|
||||||
|
|
||||||
|
if( m_getCount == m_debugEpoch )
|
||||||
|
{
|
||||||
|
Log.InfoFormat( "[ASSET CACHE]: Cached = {0}, Get = {1}, Hits = {2}%, Size = {3} bytes, Avg. A. Size = {4} bytes",
|
||||||
|
m_cachedCount, m_getCount, ( (double) m_hitCount / m_getCount ) * 100.0, m_cache.Size, m_cache.Size / m_cache.Count );
|
||||||
|
m_getCount = 0;
|
||||||
|
m_hitCount = 0;
|
||||||
|
m_cachedCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return assetBase;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ISharedRegionModule Members
|
||||||
|
/// <summary>
|
||||||
|
/// Gets region module's name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "CenomeMemoryAssetCache"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// New region is being added to server.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scene">
|
||||||
|
/// Region's scene.
|
||||||
|
/// </param>
|
||||||
|
public void AddRegion( Scene scene )
|
||||||
|
{
|
||||||
|
if( m_enabled )
|
||||||
|
scene.RegisterModuleInterface<IImprovedAssetCache>( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Close region module.
|
||||||
|
/// </summary>
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
m_enabled = false;
|
||||||
|
m_cache.Clear();
|
||||||
|
m_cache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize region module.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">
|
||||||
|
/// Configuration source.
|
||||||
|
/// </param>
|
||||||
|
public void Initialise( IConfigSource source )
|
||||||
|
{
|
||||||
|
m_cache = null;
|
||||||
|
m_enabled = false;
|
||||||
|
|
||||||
|
var moduleConfig = source.Configs[ "Modules" ];
|
||||||
|
if( moduleConfig == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var name = moduleConfig.GetString( "AssetCaching" );
|
||||||
|
Log.DebugFormat( "[XXX] name = {0} (this module's name: {1}", name, Name );
|
||||||
|
|
||||||
|
if( name != Name )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// This module is used
|
||||||
|
var maxSize = DefaultMaxSize;
|
||||||
|
var maxCount = DefaultMaxCount;
|
||||||
|
var expirationTime = DefaultExpirationTime;
|
||||||
|
|
||||||
|
var assetConfig = source.Configs[ "AssetCache" ];
|
||||||
|
if( assetConfig != null )
|
||||||
|
{
|
||||||
|
// Get optional configurations
|
||||||
|
maxSize = assetConfig.GetLong( "MaxSize", DefaultMaxSize );
|
||||||
|
maxCount = assetConfig.GetInt( "MaxCount", DefaultMaxCount );
|
||||||
|
expirationTime =
|
||||||
|
TimeSpan.FromMinutes( assetConfig.GetInt( "ExpirationTime", (int) DefaultExpirationTime.TotalMinutes ) );
|
||||||
|
|
||||||
|
// Debugging purposes only
|
||||||
|
m_debugEpoch = assetConfig.GetInt( "DebugEpoch", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
Initialize( maxSize, maxCount, expirationTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialization post handling.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Modules can use this to initialize connection with other modules.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Region has been loaded.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scene">
|
||||||
|
/// Region's scene.
|
||||||
|
/// </param>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// This is needed for all module types. Modules will register
|
||||||
|
/// Interfaces with scene in AddScene, and will also need a means
|
||||||
|
/// to access interfaces registered by other modules. Without
|
||||||
|
/// this extra method, a module attempting to use another modules'
|
||||||
|
/// interface would be successful only depending on load order,
|
||||||
|
/// which can't be depended upon, or modules would need to resort
|
||||||
|
/// to ugly kludges to attempt to request interfaces when needed
|
||||||
|
/// and unnecessary caching logic repeated in all modules.
|
||||||
|
/// The extra function stub is just that much cleaner.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public void RegionLoaded( Scene scene )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Region is being removed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scene">
|
||||||
|
/// Region scene that is being removed.
|
||||||
|
/// </param>
|
||||||
|
public void RemoveRegion( Scene scene )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
<RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectors.Asset.HGAssetBroker" />
|
<RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectors.Asset.HGAssetBroker" />
|
||||||
<RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" />
|
<RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" />
|
||||||
<RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" />
|
<RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" />
|
||||||
|
<RegionModule id="CenomeMemoryAssetCache" type="OpenSim.Region.CoreModules.Asset.CenomeMemoryAssetCache"/>
|
||||||
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
|
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
|
||||||
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
|
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
|
||||||
</Extension>
|
</Extension>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[Modules]
|
[Modules]
|
||||||
;AssetCaching = "CoreAssetCache"
|
;AssetCaching = "CoreAssetCache"
|
||||||
AssetCaching = "GlynnTuckerAssetCache"
|
AssetCaching = "GlynnTuckerAssetCache"
|
||||||
|
;AssetCaching = "CenomeMemoryAssetCache"
|
||||||
|
|
||||||
[AssetCache]
|
[AssetCache]
|
||||||
; Number of buckets for assets
|
; Number of buckets for assets
|
||||||
|
@ -16,3 +17,11 @@
|
||||||
;
|
;
|
||||||
AssetServerURI = "http://myassetserver.com:8003"
|
AssetServerURI = "http://myassetserver.com:8003"
|
||||||
|
|
||||||
|
|
||||||
|
; Optional configurations for CenomeMemoryAssetCache
|
||||||
|
; Cache size 128 MB (default: 134217728)
|
||||||
|
; MaxSize = 134217728
|
||||||
|
; Maximal asset count
|
||||||
|
; MaxCount = 4096
|
||||||
|
; Asset's expiration time (minutes)
|
||||||
|
; ExpirationTime = 30
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[Modules]
|
[Modules]
|
||||||
;AssetCaching = "CoreAssetCache"
|
;AssetCaching = "CoreAssetCache"
|
||||||
AssetCaching = "GlynnTuckerAssetCache"
|
AssetCaching = "GlynnTuckerAssetCache"
|
||||||
|
;AssetCaching = "CenomeMemoryAssetCache"
|
||||||
|
|
||||||
[AssetCache]
|
[AssetCache]
|
||||||
; Number of buckets for assets
|
; Number of buckets for assets
|
||||||
|
@ -20,3 +21,10 @@
|
||||||
AssetLoaderArgs = "assets/AssetSets.xml"
|
AssetLoaderArgs = "assets/AssetSets.xml"
|
||||||
|
|
||||||
|
|
||||||
|
; Optional configurations for CenomeMemoryAssetCache
|
||||||
|
; Cache size 128 MB (default: 134217728)
|
||||||
|
; MaxSize = 134217728
|
||||||
|
; Maximal asset count
|
||||||
|
; MaxCount = 4096
|
||||||
|
; Asset's expiration time (minutes)
|
||||||
|
; ExpirationTime = 30
|
Loading…
Reference in New Issue