aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Asset
diff options
context:
space:
mode:
authorDahlia Trimble2009-06-03 08:41:08 +0000
committerDahlia Trimble2009-06-03 08:41:08 +0000
commit9e3b592fa3636cf3d50460e303173de55bcb3920 (patch)
treeb2c39f6540fd52cc6382958f5604af1305210902 /OpenSim/Region/CoreModules/Asset
parentThanks aduffy70 for Mantis #3762: A patch to fix llGround, llGroundNormal, an... (diff)
downloadopensim-SC-9e3b592fa3636cf3d50460e303173de55bcb3920.zip
opensim-SC-9e3b592fa3636cf3d50460e303173de55bcb3920.tar.gz
opensim-SC-9e3b592fa3636cf3d50460e303173de55bcb3920.tar.bz2
opensim-SC-9e3b592fa3636cf3d50460e303173de55bcb3920.tar.xz
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.
Diffstat (limited to 'OpenSim/Region/CoreModules/Asset')
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs382
1 files changed, 382 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
new file mode 100644
index 0000000..00a8143
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -0,0 +1,382 @@
1// --------------------------------------------------------------------------------------------------------------------
2// <copyright company="" file="CenomeAssetCache.cs">
3//
4// </copyright>
5// <summary>
6//
7// </summary>
8//
9// --------------------------------------------------------------------------------------------------------------------
10using System;
11using System.Reflection;
12using log4net;
13using Nini.Config;
14using OpenSim.Framework;
15using OpenSim.Region.Framework.Interfaces;
16using OpenSim.Region.Framework.Scenes;
17
18namespace OpenSim.Region.CoreModules.Asset
19{
20 /// <summary>
21 /// Cenome memory asset cache.
22 /// </summary>
23 /// <remarks>
24 /// <para>
25 /// Cache is enabled by setting "AssetCaching" configuration to value "CenomeMemoryAssetCache".
26 /// When cache is successfully enable log should have message
27 /// "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = XXX bytes, MaxCount = XXX, ExpirationTime = XXX)".
28 /// </para>
29 /// <para>
30 /// Cache's size is limited by two parameters:
31 /// maximal allowed size in bytes and maximal allowed asset count. When new asset
32 /// is added to cache that have achieved either size or count limitation, cache
33 /// will automatically remove less recently used assets from cache. Additionally
34 /// asset's lifetime is controlled by expiration time.
35 /// </para>
36 /// <para>
37 /// <list type="table">
38 /// <listheader>
39 /// <term>Configuration</term>
40 /// <description>Description</description>
41 /// </listheader>
42 /// <item>
43 /// <term>MaxSize</term>
44 /// <description>Maximal size of the cache in bytes. Default value: 128MB (134 217 728 bytes).</description>
45 /// </item>
46 /// <item>
47 /// <term>MaxCount</term>
48 /// <description>Maximal count of assets stored to cache. Default value: 4096 assets.</description>
49 /// </item>
50 /// <item>
51 /// <term>ExpirationTime</term>
52 /// <description>Asset's expiration time in minutes. Default value: 30 minutes.</description>
53 /// </item>
54 /// </list>
55 /// </para>
56 /// </remarks>
57 /// <example>
58 /// Enabling Cenome Asset Cache:
59 /// <code>
60 /// [Modules]
61 /// AssetCaching = "CenomeMemoryAssetCache"
62 /// </code>
63 /// Setting size and expiration time limitations:
64 /// <code>
65 /// [AssetService]
66 /// ; 256 MB (default: 134217728)
67 /// MaxSize = 268435456
68 /// ; How many assets it is possible to store cache (default: 4096)
69 /// MaxCount = 16384
70 /// ; Expiration time - 1 hour (default: 30 minutes)
71 /// ExpirationTime = 60
72 /// </code>
73 /// </example>
74 public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule
75 {
76 /// <summary>
77 /// Cache's default maximal asset count.
78 /// </summary>
79 /// <remarks>
80 /// <para>
81 /// Assuming that average asset size is about 32768 bytes.
82 /// </para>
83 /// </remarks>
84 public const int DefaultMaxCount = 4096;
85
86 /// <summary>
87 /// Default maximal size of the cache in bytes
88 /// </summary>
89 /// <remarks>
90 /// <para>
91 /// 128MB = 128 * 1024^2 = 134 217 728 bytes.
92 /// </para>
93 /// </remarks>
94 public const long DefaultMaxSize = 134217728;
95
96 /// <summary>
97 /// Asset's default expiration time in the cache.
98 /// </summary>
99 public static readonly TimeSpan DefaultExpirationTime = TimeSpan.FromMinutes( 30.0 );
100
101 /// <summary>
102 /// Log manager instance.
103 /// </summary>
104 private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
105
106 /// <summary>
107 /// Cache object.
108 /// </summary>
109 private ICnmCache<string, AssetBase> m_cache;
110
111 /// <summary>
112 /// Count of cache commands
113 /// </summary>
114 private int m_cachedCount;
115
116 /// <summary>
117 /// How many gets before dumping statistics
118 /// </summary>
119 /// <remarks>
120 /// If 0 or less, then disabled.
121 /// </remarks>
122 private int m_debugEpoch;
123
124 /// <summary>
125 /// Is Cenome asset cache enabled.
126 /// </summary>
127 private bool m_enabled;
128
129 /// <summary>
130 /// Count of get requests
131 /// </summary>
132 private int m_getCount;
133
134 /// <summary>
135 /// How many hits
136 /// </summary>
137 private int m_hitCount;
138
139 /// <summary>
140 /// Initialize asset cache module with default parameters.
141 /// </summary>
142 public void Initialize()
143 {
144 Initialize( DefaultMaxSize, DefaultMaxCount, DefaultExpirationTime );
145 }
146
147 /// <summary>
148 /// Initialize asset cache module, with custom parameters.
149 /// </summary>
150 /// <param name="maximalSize">
151 /// Cache's maximal size in bytes.
152 /// </param>
153 /// <param name="maximalCount">
154 /// Cache's maximal count of assets.
155 /// </param>
156 /// <param name="expirationTime">
157 /// Asset's expiration time.
158 /// </param>
159 public void Initialize( long maximalSize, int maximalCount, TimeSpan expirationTime )
160 {
161 if( maximalSize <= 0 || maximalCount <= 0 )
162 {
163 Log.Info( "[ASSET CACHE]: Cenome asset cache is not enabled." );
164 m_enabled = false;
165 return;
166 }
167
168 if( expirationTime <= TimeSpan.Zero )
169 {
170 // Disable expiration time
171 expirationTime = TimeSpan.MaxValue;
172 }
173
174 // Create cache and add synchronization wrapper over it
175 m_cache =
176 CnmSynchronizedCache<string, AssetBase>.Synchronized( new CnmMemoryCache<string, AssetBase>(
177 maximalSize, maximalCount, expirationTime ) );
178 m_enabled = true;
179 Log.InfoFormat(
180 "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = {0} bytes, MaxCount = {1}, ExpirationTime = {2})",
181 maximalSize,
182 maximalCount,
183 expirationTime );
184 }
185
186 #region IImprovedAssetCache Members
187
188 /// <summary>
189 /// Cache asset.
190 /// </summary>
191 /// <param name="asset">
192 /// The asset that is being cached.
193 /// </param>
194 public void Cache( AssetBase asset )
195 {
196 long size = asset.Data != null ? asset.Data.Length : 1;
197 m_cache.Set( asset.ID, asset, size );
198 m_cachedCount++;
199 }
200
201 /// <summary>
202 /// Clear asset cache.
203 /// </summary>
204 public void Clear()
205 {
206 m_cache.Clear();
207 }
208
209 /// <summary>
210 /// Expire (remove) asset stored to cache.
211 /// </summary>
212 /// <param name="id">
213 /// The expired asset's id.
214 /// </param>
215 public void Expire( string id )
216 {
217 m_cache.Remove( id );
218 }
219
220 /// <summary>
221 /// Get asset stored
222 /// </summary>
223 /// <param name="id">
224 /// The asset's id.
225 /// </param>
226 /// <returns>
227 /// Asset if it is found from cache; otherwise <see langword="null"/>.
228 /// </returns>
229 /// <remarks>
230 /// <para>
231 /// Caller should always check that is return value <see langword="null"/>.
232 /// Cache doesn't guarantee in any situation that asset is stored to it.
233 /// </para>
234 /// </remarks>
235 public AssetBase Get( string id )
236 {
237 m_getCount++;
238 AssetBase assetBase;
239 if( m_cache.TryGetValue( id, out assetBase ) )
240 m_hitCount++;
241
242 if( m_getCount == m_debugEpoch )
243 {
244 Log.InfoFormat(
245 "[ASSET CACHE]: Cached = {0}, Get = {1}, Hits = {2}%, Size = {3} bytes, Avg. A. Size = {4} bytes",
246 m_cachedCount,
247 m_getCount,
248 ((double) m_hitCount / m_getCount) * 100.0,
249 m_cache.Size,
250 m_cache.Size / m_cache.Count );
251 m_getCount = 0;
252 m_hitCount = 0;
253 m_cachedCount = 0;
254 }
255
256 return assetBase;
257 }
258
259 #endregion
260
261 #region ISharedRegionModule Members
262
263 /// <summary>
264 /// Gets region module's name.
265 /// </summary>
266 public string Name
267 {
268 get { return "CenomeMemoryAssetCache"; }
269 }
270
271 /// <summary>
272 /// New region is being added to server.
273 /// </summary>
274 /// <param name="scene">
275 /// Region's scene.
276 /// </param>
277 public void AddRegion( Scene scene )
278 {
279 if( m_enabled )
280 scene.RegisterModuleInterface<IImprovedAssetCache>( this );
281 }
282
283 /// <summary>
284 /// Close region module.
285 /// </summary>
286 public void Close()
287 {
288 m_enabled = false;
289 m_cache.Clear();
290 m_cache = null;
291 }
292
293 /// <summary>
294 /// Initialize region module.
295 /// </summary>
296 /// <param name="source">
297 /// Configuration source.
298 /// </param>
299 public void Initialise( IConfigSource source )
300 {
301 m_cache = null;
302 m_enabled = false;
303
304 IConfig moduleConfig = source.Configs[ "Modules" ];
305 if( moduleConfig == null )
306 return;
307
308 string name = moduleConfig.GetString( "AssetCaching" );
309 Log.DebugFormat( "[XXX] name = {0} (this module's name: {1}", name, Name );
310
311 if( name != Name )
312 return;
313
314 // This module is used
315 long maxSize = DefaultMaxSize;
316 int maxCount = DefaultMaxCount;
317 TimeSpan expirationTime = DefaultExpirationTime;
318
319 IConfig assetConfig = source.Configs[ "AssetCache" ];
320 if( assetConfig != null )
321 {
322 // Get optional configurations
323 maxSize = assetConfig.GetLong( "MaxSize", DefaultMaxSize );
324 maxCount = assetConfig.GetInt( "MaxCount", DefaultMaxCount );
325 expirationTime =
326 TimeSpan.FromMinutes( assetConfig.GetInt( "ExpirationTime", (int) DefaultExpirationTime.TotalMinutes ) );
327
328 // Debugging purposes only
329 m_debugEpoch = assetConfig.GetInt( "DebugEpoch", 0 );
330 }
331
332 Initialize( maxSize, maxCount, expirationTime );
333 }
334
335 /// <summary>
336 /// Initialization post handling.
337 /// </summary>
338 /// <remarks>
339 /// <para>
340 /// Modules can use this to initialize connection with other modules.
341 /// </para>
342 /// </remarks>
343 public void PostInitialise()
344 {
345 }
346
347 /// <summary>
348 /// Region has been loaded.
349 /// </summary>
350 /// <param name="scene">
351 /// Region's scene.
352 /// </param>
353 /// <remarks>
354 /// <para>
355 /// This is needed for all module types. Modules will register
356 /// Interfaces with scene in AddScene, and will also need a means
357 /// to access interfaces registered by other modules. Without
358 /// this extra method, a module attempting to use another modules'
359 /// interface would be successful only depending on load order,
360 /// which can't be depended upon, or modules would need to resort
361 /// to ugly kludges to attempt to request interfaces when needed
362 /// and unnecessary caching logic repeated in all modules.
363 /// The extra function stub is just that much cleaner.
364 /// </para>
365 /// </remarks>
366 public void RegionLoaded( Scene scene )
367 {
368 }
369
370 /// <summary>
371 /// Region is being removed.
372 /// </summary>
373 /// <param name="scene">
374 /// Region scene that is being removed.
375 /// </param>
376 public void RemoveRegion( Scene scene )
377 {
378 }
379
380 #endregion
381 }
382}